ACM-ICPC 2018 南京賽區網路預賽 C GDY (暴力模擬)
阿新 • • 發佈:2019-02-20
分析:暴力模擬即可
程式碼:
#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]); } } }