ACM-ICPC 2018 南京赛区网络预赛 C GDY (暴力模拟)

题目链接:https://nanti.jisuanke.com/t/30992

分析:暴力模拟即可

代码:

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <queue>
#include <stack>
#include <cstdio>
#include <vector>
#include <iomanip>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define ll long long
#define mod 1000000007
#define lowbit(x) (x&(-x))
#define mem(a,b) memset(a,b,sizeof(a))
#define FRER() freopen("in.txt","r",stdin);
#define FREW() freopen("out.txt","w",stdout);

using namespace std;

typedef pair<int,int> pii;
const int N =100000 + 7 , M = 200000 + 7, inf = 0x3f3f3f3f ;
int n,m;
int a[210][20],b[20007],num[210];//a[i][j]为第i个人j牌的数目,b[i]为待取的牌,num[i]为第i个人牌总和
int main(){
    FRER();
    int T,kase = 1;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&n,&m);
        mem(a,0);
        mem(num,0);
        for(int i=1;i<=m;i++) {
            scanf("%d",&b[i]);
            if(b[i]==1) b[i] = 14;
            if(b[i]==2) b[i] = 15;
        }
        int k = 1;
        for(int i=0;i<n;i++){
            if(k>m) break;
            int cnt = 5;
            while(cnt--&&k<=m){
                num[i]+=b[k];
                a[i][b[k++]]++;
            }
        }
        int cnt = 0 , p = 1 , now , id = 0; // cnt为未出牌的人数,p%n为当前出牌人,now 最后出牌,id为最后出牌人
        int j = 3;//第一个人出牌
        while(!a[0][j]) j++;
        now = j;
        a[0][j]--;
        num[0]-=j;
        while(1){
            if(cnt==n-1){//当没人能要的上最后出牌人的牌,摸牌
                cnt = 0;
                for(int i=id;i<id+n;i++){//摸牌
                    if(k>m) break;
                    a[i%n][b[k]]++;
                    num[i%n]+=b[k++];
                }
                //最后出牌人出牌
                int j = 3;
                while(!a[id][j]&&j<=15) j++;
                now = j;
                num[id]-=j;
                a[id][j]--;
                if(num[id]==0){
                    break;
                }
                p = id + 1;
            }else {
                int pp = p%n;
                //判断是否出牌
                if(a[pp][now+1]){
                    id = pp;
                    a[pp][now+1]--;
                    num[pp]-=(now+1);
                    now = now+1;
                    if(num[pp]==0){
                        break;
                    }
                    cnt = 0;
                }else if(now!=15&&a[pp][15]){
                    id = pp;
                    now = 15;
                    a[pp][15]--;
                    num[pp]-=15;
                    if(num[pp]==0){
                        break;
                    }
                    cnt = 0;
                }else
                    cnt++;
                p++;
            }
        }
        //由于把1,2转化为14,15,所以最后要减去相应的增加量
        for(int i=0;i<n;i++){
            if(a[i][14]) num[i]-=13*a[i][14];
            if(a[i][15]) num[i]-=13*a[i][15];
        }
        printf("Case #%d:\n",kase++);
        for(int i=0;i<n;i++){
            if(!num[i]) printf("Winner\n");
            else printf("%d\n",num[i]);
        }
    }
}

 

posted @ 2018-09-03 21:16  dslybyme7  阅读(120)  评论(0编辑  收藏  举报