ACM-ICPC 2018 南京赛区网络预赛 C GDY(模拟)
https://nanti.jisuanke.com/t/30992
题意
把m张牌(牌上数字范围是1-13)放到栈里
n个人,每个人首次从栈顶取5张牌,轮流取
取完牌后,第1个人出他手里最小的牌,
然后2-n个人轮流出牌,每次出牌的选择是:
(1)出比前一个人的牌大1的牌
(2)在前一个牌不是2的时候可以出2
(优先选择(1)出牌方式出牌)
如果第i个人没有能出的牌,他就“过”
如果第X个人出完牌后,走了一圈到了X,中间没一个人能出牌,那么从X开始所有人要从栈中取一张牌,接着,X出他手里最小的牌。
如果栈里没牌了,那么就跳过取牌的环节
谁先出完牌谁胜,剩下的人输出他的惩罚(惩罚是手里牌的值之和)
分析
根据题意模拟就好,比赛时来不及做呀,我太弱了
#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; }