链接:
https://nanti.jisuanke.com/t/30992
题意:
有n个人(标号1-n)玩牌,牌的点数从1-13,其中2>1>13>12>…>3(和斗地主的大小规则相同嘛),告诉你牌池里有哪些牌(含顺序)。
·要求从1号开始,每人一次性摸5张牌以开始游戏,之后按照1、2、3…n、1、2的顺序出牌,开始出牌的人会选择自己最小的牌来出,出牌规则要求只能出比之前打出去的牌大1,或者出最大的一张牌——2,比如上张牌是8,下家就只能接9或者2,出10之类的是非法的。如果一个人没有牌可出,它就会被跳过。
·如果A出牌之后一整轮没有人出牌,那么从A开始,包括A,n个人每个人抽一张牌,然后从A开始,出A最小的牌,以开始下一轮
如果牌取完了,取牌流程取消,其他依旧。
最后,先逃完牌的为Winner,剩下的人计算罚点,为手上所有牌的点数之和。
数据保证每人先取5张牌的流程完之后,n个人手头都有牌(当然最后一个人不一定是5张)
样例输入:
2
2 10
3 5 7 9 11 4 6 8 10 12
3 15
4 5 6 7 8 9 10 11 12 13 2 2 2 2 2
样例输出:
Case #1:
Winner
12
Case #2:
26
55
Winner
思路:
数据规模并不大(For all the test cases, it’s guaranteed that the sum of m doesn’t exceed 4e5.)
作为适合打蓝桥杯水赛的暴力蒟蒻选手- -模拟是长项,所以模拟他们的打牌过程就好了。
流程:将牌池存入一个数组(或者按照题意说的,push入stack,然后每次取用就取top,然后pop)
一个变量cnt表示当前取到的牌的序号。如果cnt == n。然后n人轮流摸5张牌,完了之后从1开始,找自己最小的牌打,2接,3接……直到出现Winner 或者 到某一圈结束,谁都接不了某人出的牌,那么每人摸一张牌,再战……
产生Winner之后,游戏即刻结束,清算积分。
代码:
#include <bits/stdc++.h>
using namespace std;
int a[210][14],b[20010],c[210],n,m,cnt,winner;
inline void get(int id){
if(cnt < m)a[id][b[cnt++]]++,c[id]++;
}
inline void decrease(int i,int j){
a[i][j]--,c[i]--;
if(!c[i])winner = i;
}
void print(){
for(int i = 0;i < n;i++){
if(i == winner)puts("Winner");
else{
int sum = 0;
for(int j = 1;j <= 13;j++)sum += j*a[i][j];
printf("%d\n",sum);
}
}
}
int main(){
int T;
scanf("%d",&T);
for(int t = 1;t <= T;t++){
bool flag = false;
cnt = 0,winner = -1;
int id = 0,p = 0,now;
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
scanf("%d %d",&n,&m);
for(int i = 0;i < m;i++)scanf("%d",&b[i]);
for(int i = 0;i < n;i++)for(int j = 0;j < 5;j++)get(i);
while(winner == -1){
if(id == p%n){
if(flag){
for(int i = id;i < n;i++)get(i);
for(int i = 0;i < id;i++)get(i);
}
flag = true;
for(int i = 3;i <= 13;i++)
if(a[id][i]){
now = i;
decrease(id,now);
goto label;
}
for(int i = 1;i <= 3;i++)
if(a[id][i]){
now = i;
decrease(id,now);
goto label;
}
label:
p++;
}
else{
if(now == 13){
if(a[p%n][1]){
now = 1;
id = p%n;
decrease(id,now);
}
else if(a[p%n][2]){
now = 2;
id = p%n;
decrease(id,now);
}
}
else if(now != 2){
if(a[p%n][now+1]){
now++;
id = p%n;
decrease(id,now);
}
else if(a[p%n][2]){
now = 2;
id = p%n;
decrease(id,now);
}
}
p++;
}
}
printf("Case #%d:\n",t);
print();
}
return 0;
}
好菜啊QAQ,文文姐说用goto会被队友打死。。