# Simulation# String Parsing# Greedy

e263 - 九九

🔗 前往 ZeroJudge 原題

題目描述

本題模擬一個名為“九九”的撲克牌遊戲。遊戲中,玩家輪流出牌,每張牌對總和有不同的影響。目標是模擬遊戲過程,判斷是否有玩家爆點(總和超過 99),並輸出結果。如果有人爆點,輸出該玩家的編號;否則,輸出最終的總和。

解題思路

這題的核心是模擬遊戲流程。需要維護以下資訊:

  1. 玩家數量 n
  2. 已出牌數量 m
  3. 當前總和 sum
  4. 當前出牌玩家的編號 it
  5. 出牌方向 way (順時針或逆時針)
  6. 作弊標誌 ans 和作弊玩家編號 ans1

程式碼逐行解析每張牌,根據牌面值更新總和、出牌玩家編號和出牌方向。如果總和超過 99,則設定作弊標誌並記錄作弊玩家編號。最後,根據作弊標誌輸出結果。

複雜度分析

  • 時間複雜度: O(m),其中 m 是已出牌數量。程式碼需要遍歷每一張牌來模擬遊戲過程。
  • 空間複雜度: O(1)。程式碼使用的額外空間是常數級別,不隨輸入大小變化。

程式碼

#include <iostream>
using namespace std;
int main(){
	int a,b;
	while(cin >> a >> b){
		int it=0,way=1,sum=0,ans1=0;
		bool ans=0;
		string m;
		while(b--){
			cin >> m;
			if(ans==0){
				it+=way;
				if(it>a)
					it-=a;
				else if(it<=0)
					it+=a;
				if(m=="A")
					sum=0;
				else if(m=="2"||m=="3"||(m>="6"&&m<="9"))
					sum+=m[0]-48;
				else if(m=="4")
					way*=-1;
				else if(m[0]=='5'){
					int k=0;
					for(int i=2;m[i]!=')';++i){
						k*=10;
						k+=m[i]-48;
					}
					it=k-way;
				}
				else if(m[0]=='1'){
					if(m[2]=='+')
						sum+=10;
					else
						sum=max(sum-10,0);
				}
				else if(m[0]=='Q'){
					if(m[1]=='+')
						sum+=20;
					else
						sum=max(sum-20,0);
				}
				else if(m=="K")
					sum=99;
				if(sum>99){
					ans=1;
					ans1=it;
				}
			}
		}
		if(ans)
			cout << ans1 << " cheated!\n";
		else
			cout << "The sum is " << sum << "\n";
	}
}

Discussion