[2018.11.03 T4] 7w523

7w523

題目描述

你玩過7王523嗎?

這個撲克牌遊戲可以 2~5 個人玩,最開始的時候,每人 55 張牌,莊家 66 張牌。莊家首先出牌,然後輪流出牌或不出牌。

第一個出牌的人可以打出任意牌,後面的人必須比前面的牌大才能出牌,且牌型必須要和前面人出牌的牌型一致或大於前面人的牌型。

牌的大小關係是 7>大王>小王>5>2>3>A>K>Q>J>10>9>8>6>4.不區分花色。

牌型有:對子(兩張牌點數一樣),炸彈(三張牌一樣),氫彈(四張牌一樣)

牌型的大小關係是:氫彈>炸彈>對子、單牌

另外還有一種特殊的出牌規則,如果有人出單牌,某人手上有一樣點數的對子,則有對子的人可以忽略出牌順序直接“碰”。在“碰”後,後面只有炸彈或氫彈可以出。(比如甲出單牌,後面只要有人有碰,一定是先滿足碰)

當某個人打出的牌沒人要時,本輪出牌結束,最後一個出牌的人取得本輪勝利,本輪出的牌就是勝利的人的積分,11 張牌記 11 分。再由勝利的人開始在剩餘牌中按順序拿幾張牌和手上的牌湊夠五張,接下來按順序另外的人也從剩餘牌中按順序拿夠 55 張。 如果牌庫中牌的數量不夠某個人拿夠55張, 則停止拿牌環節。 如果發牌環節結束後某個玩家沒有牌, 則整個遊戲結束, 同時每個玩家的得分加上其手牌數量。

例如:

甲:2 4 4 6 K

乙:3 8 8 J 10

丙:K K 4 A A

剩餘牌:7 7 2

假設出牌順序是甲、乙、丙;

第一輪:甲先出 66,則乙可以出 JJ101033;丙如果不要,則甲可以出 22。這個時候沒有人有牌能夠大過 22,該輪出牌結束,甲獲得勝利可以得到 33 個積分。接下來甲可以從剩餘牌中獲得 2277,而乙可以獲得 22。丙沒有出牌就不能拿。

第二輪:甲出 KK,這個時候丙可以跳過乙優先進行“碰”,由於其他人沒有炸彈,所以丙獲得該輪勝利,得到 33 個積分。

爲了簡化問題,我們不考慮獲勝的策略。也就是說輪到某人出牌,如果他手上的牌有大於前面人出的牌,則他就打出剛好大於前面的牌(有出必出),有“碰”必“碰”。 比如第一個人出 QQ,第二個人牌是 K333K333,第三個人牌是 QQJQQJ,則第三個人會先碰出來。因爲對於第二個人來說他優先選擇出 KK,所以第三個人先碰。

每一輪第一個出牌的人,優先出手中最小的對子(爲了儘可能讓別人要不起, 7 除外),沒有對子就出最小的單牌,沒有單牌出對 7,沒有對 7 出最小的炸彈,沒有炸彈出氫彈。接下來輪流出牌,出的牌型必須和前面一至或大於前面的牌型,對子、炸彈、氫彈不能拆開出,出牌的原則的剛好大於前面的牌,如果沒有大過前面的牌就 PASSPASS,由後面一個人出牌。如果一個人出的牌其他人都 PASSPASS,則本輪結束,最後一個出牌的爲勝利者。

**注:**大王與小王不在一起算單牌,大王和小王在一起算炸彈(不能拆開),且是僅次於 777777 的最大炸彈。任何氫彈都大於任何炸彈, 包括王炸。若牌庫無牌, 且某玩家出牌後剛好打完, 這一回合仍然需要進行完纔算遊戲結束。

開始的時候,第一個人自動作爲莊家先拿前面的 66 張牌,接下來玩家依次拿 55 張(若不夠則停止拿牌環節)。當沒有剩餘的牌且發牌環節某個玩家手上沒有牌,遊戲結束,其他玩家手中的沒有打出去的牌自動算爲該玩家的積分。

輸入輸出格式
輸入格式

一共 22 行;

第一行是一個整數 MM 表示玩家人數,第二行是一個字符串表示初始牌的順序,其中大王用GG 表示,小王用 FF 表示,10 用 XX 表示。

輸出格式

MM 行,每行是一個整數,表示第 ii 個玩家最後獲得的積分。

輸入輸出樣例
輸入樣例#1:
3
25G36Q3885XKK4AA77A
輸出樣例#1:
13
2
4

樣例解釋

第一輪:第一個人出 6,然後第二個人出 X,第三個人不要,第一個人出 Q,第二個人出 3,第三個人不要,第一個人出 2,第二個人出 5、三個人不要,第一個人出 G,第二三個人不要,第一輪結束。第一個人獲得積分 7,然後獲得 77A 三張牌

第二輪:第一個人出 A, 第三個人有碰優先由第三個人碰,第三個人碰後,沒有人有炸彈,該輪第三個人勝利。第三個人獲得積分 3

第三輪:第三個人出對 K,第一個人出對 7,第一個人取得本輪勝利獲得積分 4 第四輪:第一個人出 3,第二個人、第三個人 pass,第一個人取得勝利獲得積分 1 第五輪:第一個人出 5,第一個人取得勝利獲得積分 1。遊戲結束。最後得分:

第一個人:13

第二個人:2

第三個人:4

【數據特點】

對於 100%數據,保證開始每個人至少有一張牌。一副牌中最多隻有一張大王和小王,每個點數的牌張數不超過 4,所有字母均爲大寫,只有 J,Q,K,A,G,X,F,9,8,7,6,5,4,3,2 這些牌。

測試點 玩家人數 撲克牌總數 特殊情況
1 2 11\le 11 沒有碰、炸彈、氫彈
2 2 54\le 54 沒有炸彈、氫彈
3 3 16\le 16
4 3 54\le 54 沒有碰
5 3 54\le 54 沒有炸彈、氫彈
6 4 21\le 21 沒有碰
7 4 21\le 21 沒有王炸
8 4 54\le 54 沒有碰、炸彈、氫彈
9 4 54\le 54 沒有炸彈、氫彈
10 4 54\le 54
題解

辣雞大模擬,不過我大概是全網最短的代碼:
1.png

代碼
#include<cstdio>
#include<cstring>
#define put(pos,typ,siz) my[pos][siz]=0,cot[pos]-=typ,flag=1,last=(sd){pos,typ,siz}
const int N=15;
struct sd{int pos,typ,siz;}last;
int val[256],my[6][16],cot[6],sta[55],scr[6],top,n,flag;
char ch[55];
int kind[]={0,'4','6','8','9','X','J','Q','K','A','3','2','5','F','G','7'};
void getcard(int pos,int siz)
{
	for(;cot[pos]<siz&&top;++my[pos][sta[top--]],++cot[pos]);
	if(my[pos][13]&&my[pos][14])my[pos][13]=0,my[pos][14]=3;
}
void putcard(int pos)
{
	int typ=last.typ,siz=last.siz;
	if(!typ)
	{
		for(int i=1;i<N;++i)if(my[pos][i]==2){put(pos,2,i);return;}
		for(int i=1;i<=N;++i)if(my[pos][i]==1){put(pos,1,i);return;}
		if(my[pos][N]==2){put(pos,2,N);return;}
		for(int i=1;i<=N;++i)if(my[pos][i]==3){if(i==14)cot[pos]+=1;put(pos,3,i);return;}
		for(int i=1;i<=N;++i)if(my[pos][i]==4){put(pos,4,i);return;}
	}
	for(int i=1;i<=N;++i)if(my[pos][i]==typ&&i>siz){if(i==14&&typ==3)cot[pos]+=1;put(pos,typ,i);return;}
	for(int j=(typ==1?3:typ+1);j<=4;++j)for(int i=1;i<=N;++i)if(my[pos][i]==j){if(i==14&&j==3)cot[pos]+=1;put(pos,j,i);return;}
	flag=0;
}
bool peng(){for(int i=0;i<n;++i)if(last.typ==1&&my[i][last.siz]==2)return put(i,2,last.siz),last=(sd){i,3,-1},1;return 0;}
void game()
{
	for(int i=1;i<=N;++i)val[kind[i]]=i;
	for(int i=strlen(ch+1);i;--i)sta[++top]=val[ch[i]];
	getcard(0,6);for(int i=1;i<n;++i)getcard(i,5);
	for(int pos,cnt;;last.typ=0,scr[last.pos]+=cnt)
	{
		for(int i=0;i<n;++i)getcard((last.pos+i)%n,5);
		if(!top)for(int i=0;i<n;++i)if(!cot[i])return;
		putcard(last.pos),cnt=last.typ;if(last.typ==3&&last.siz==14)cnt-=1;
		if(peng())cnt+=2,pos=last.pos;
		for(pos=(last.pos+1)%n;pos!=last.pos;pos=(pos+1)%n,flag=0)
		{
			putcard(pos);
			if(flag){cnt+=last.typ;if(last.typ==3&&last.siz==14)cnt-=1;}
			if(peng())cnt+=2,pos=last.pos;
		}
	}
}
void in(){scanf("%d%s",&n,ch+1);}
void ac(){game();for(int i=0;i<n;++i)printf("%d\n",scr[i]+cot[i]);}
int main(){in(),ac();}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章