题目:传送门
ps:一是用数组模拟很方便(我用set写炸了),二是判定什么时候结束(炒鸡重要),当某个人出完了手中所有的牌并且牌堆里没有牌的时候,游戏结束。
pps:考虑这种情况:当前这个人出完手中所有的牌,并且牌堆中还有牌,但牌堆的中的牌较少,不够每个人重新拿一张牌,尤其是还没轮到他拿牌,牌堆就没牌了。那么下面的程序就有bug,但评测姬过了。。。
int n, m, res; int p[300][20], num[300]; queue<int> q; bool check(int pos) { if (!num[pos] && q.empty()) { res = pos; return true; } return false; } void Play() { int pre = -1, now = 1, flag = -1; int t = 0; while(flag == -1) { if (pre == -1) { Rep(i, 3, 15) if (p[now][i]) { pre = i; p[now][i]--; num[now]--; t = 0; break; } if (check(now)) flag = 1; } else if (pre != 15) { if (p[now][pre + 1]) { pre = pre + 1; p[now][pre]--; num[now]--; t = 0; if(check(now)) flag = 1; } else if (p[now][15]) { pre = 15; p[now][15]--; num[now]--; t = 0; if (check(now)) flag = 1; } else t++; } else t++; now++; if (now > n) now = 1; if (t >= n - 1) { rep(i, 0, n) { if (q.empty()) break; int tp = (now + i) % n; p[tp == 0 ? n : tp][q.front()]++; q.pop(); num[tp == 0 ? n : tp]++; } pre = -1; } } } int main() { int cas = 0; BEGIN() { sc(n), sc(m); mem(p, 0), mem(num, 0); while(!q.empty()) q.pop(); Rep(i, 1, m) { int x; sc(x); if (x == 1) x = 14; if (x == 2) x = 15; if (i > 5 * n) q.push(x); else { p[(i - 1) / 5 + 1][x]++; num[(i - 1) / 5 + 1]++; } } printf("Case #%d: ", ++cas); Play(); Rep(i, 1, n) { if (i == res) { puts("Winner"); } else { int tp = 0; Rep(j, 3, 15) { int x = (j > 13 ? j - 13 : j); tp += x * p[i][j]; } pr(tp); } } } return 0; }