HihoCoder 1830 Cheat ICPC2018 北京网络赛

//写完和贴吧群dalao的代码比了一下 结果发现总是有更好的写法让你规避bug - -郁闷
https://paste.ubuntu.com/p/8RRBw7jrHQ/

#include <bits/stdc++.h> using namespace std; #define LL long long const int maxn=2e2+10; char r[15]="123456789AJKQ"; char l[15]="A234567891JQK"; const int n=13; int rnk,h,islie,cardNum; char cur; #define vp vector<pair<char,int> > #define nxtp(i) (i==3? 0:i+1) #define nxtr(i) (i==12? 0:i+1) vp desk,stmt; char s[100]; struct player { int mp[128]; int me; void initplayer(int m,char *s) { memset(mp,0,sizeof mp);me=m; int cnt=0; for(int i=0;s[i];i++) { if(!isalnum(s[i]))continue; mp[s[i]]++;cnt++;if(s[i]=='1')i++; } // if(cnt!=13)while(1); } void out(){ for(int i=0;i<n;i++){ int t=mp[l[i]]; assert(t>=0&&t<=4); while(t--){ if(l[i]=='1') printf("10 "); else printf("%c ",l[i]); } }puts(""); } char OneminiLexicoRank(int cur=-1) //注意这里要找的排除本身 { for(int i=0;i<n;i++) if(mp[r[i]]&&r[i]!=cur)return r[i]; // while(1); return 0; } char leastMiniLexicoRank() { int mi=99,id; for(int i=0;i<n;i++) { if(mp[r[i]]&&mp[r[i]]<mi)mi=mp[r[i]],id=r[i]; } return mi==99? 0:id; } void putcard() { #define pb(c,x) stmt.push_back(make_pair(c,x)) stmt.clear();islie=0; if(me==0){ cardNum=1; if(mp[cur]){ pb(cur,1);return ; //1 card } char idx=OneminiLexicoRank(); pb(idx,1);islie=1; } if(me==1){ if(mp[cur]){ pb(cur,mp[cur]);cardNum=mp[cur];return ; //all card } char idx=OneminiLexicoRank(); pb(idx,1);islie=1;cardNum=1; } if(me==2) { if(mp[cur]){ pb(cur,mp[cur]);cardNum=1;return ; //all card } char idx=leastMiniLexicoRank(); pb(idx,mp[idx]); islie=1;cardNum=mp[idx]; } if(me==3) { cardNum=mp[cur]; if(mp[cur]) pb(cur,mp[cur]); if(mp[cur]>=3) return ; //3 or 4 card char idx=OneminiLexicoRank(cur); //注意这里如果没找到就不是lie if(idx) pb(idx,1); islie=idx>0; cardNum+=(idx>0); } } bool emptied(){ for(int i=0;i<n;i++)if(mp[r[i]])return false; return true; } bool willEmpty(player &hold) { hold.deal(stmt,-1); bool flag=hold.emptied(); hold.deal(stmt,1); return flag; } bool wantChallenge(player &hold) { if(nxtp(h)==me&&me<=1&&mp[l[nxtr(rnk)]]==0) return true; if(me==0 && mp[l[rnk]]+cardNum>4) return true; if(me==2 && mp[l[rnk]]==4) return true; if(me==3 && willEmpty(hold)) return true; return false; } void deal(vp &q,int f=1) { for(auto &i:q) mp[i.first]+=f*i.second; } void comeOnBaby(player &holder) { if(islie){ holder.deal(desk,1); }else{ deal(desk,1);deal(stmt,1);holder.deal(stmt,-1); } desk.clear(); } int gettor() { int ret=0; for(int i=0;i<n;i++)ret+=mp[r[i]];return ret; } }; player p[4]; int main() { #ifdef shuaishuai freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); #endif // shuaishuai while(~scanf("%s",s)) { int len=strlen(s);gets(s+len); for(int i=0;i<4;i++) { if(i)gets(s); p[i].initplayer(i,s); } desk.clear(); for(rnk=0,h=0;;h=nxtp(h),rnk=nxtr(rnk)) { cur=l[rnk]; p[h].putcard(); int sb=0; for(int i=nxtp(h);i!=h;i=nxtp(i)){ if(p[i].wantChallenge(p[h])){ sb=1;p[i].comeOnBaby(p[h]); break; } } if(!sb) { for(auto &i:stmt) desk.push_back(i); p[h].deal(stmt,-1); } if(p[h].emptied()) { break; } } int tot=0; for(int i=0;i<4;i++)tot+=p[i].gettor(); for(auto &i:desk) tot+=i.second; // printf("%d\n",tot); assert(tot==52); for(int i=0;i<4;i++) { if(i==h) puts("WINNER"); else p[i].out(); } } return 0; }

 

posted @ 2018-10-17 04:14  BIack_Cat  阅读(207)  评论(0编辑  收藏  举报