题解 P2668 【斗地主】

hicc0305

2018-07-24 15:09:16

Personal

纯属暴搜题 先处理单顺,然后双顺,三顺。 顺子处理完后,处理四带二(单,对),三带一、二 剩下的其实都一样,因为剩下的单排、对子、炸弹、三连……都只涉及一种牌,只要在dfs最后同一处理即可 另外……花色不要理他。。。 ```cpp #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; int T,n,ans; int col[200]; bool shun(int x) { return (col[x] && col[x+1] && col[x+2] && col[x+3] && col[(x+3)%13+1]); } bool liand(int x) { return (col[x]>=2 && col[x+1]>=2 && col[(x+1)%13+1]>=2); } bool slian(int x) { return (col[x]>=3 && col[x%13+1]); } void dfs(int dep,int num) { if(dep>=ans) return; if(num==n) { ans=dep; return; } for(int i=3;i<=10;i++) { if(!shun(i)) continue; int k=i,cnt=1; col[k]--; while(k!=1) { cnt++,k++; if(k>13) k%=13; if(!col[k]) { col[k]--; break; } col[k]--; if(cnt>=5) dfs(dep+1,num+cnt); } col[k]++; while(k!=i) { k--; if(k==0) k+=13; col[k]++; } }//单顺 for(int i=3;i<=12;i++) { if(!liand(i)) continue; int k=i,cnt=1; col[k]-=2; while(k!=1) { cnt++,k++; if(k>13) k%=13; if(col[k]<2) { col[k]-=2; break; } col[k]-=2; if(cnt>=3) dfs(dep+1,num+2*cnt); } col[k]+=2; while(k!=i) { k--; if(k==0) k+=13; col[k]+=2; } }//双顺 for(int i=3;i<=13;i++) { if(!slian(i)) continue; int k=i,cnt=1; col[k]-=3; while(k!=1) { cnt++,k++; if(k>13) k%=13; if(col[k]<3) { col[k]-=3; break; } col[k]-=3; if(cnt>=2) dfs(dep+1,num+3*cnt); } col[k]+=3; while(k!=i) { k--; if(k==0) k+=13; col[k]+=3; } }//三顺 int k=1; while(k<=13) { if(col[k]==4) break; k++; } if(k<=13) { col[k]=0; for(int i=0;i<=13;i++) for(int j=0;j<=13;j++) { if(i==j) continue; if(col[i]>=2 && col[j]>=2) { col[i]-=2,col[j]-=2; dfs(dep+1,num+8); col[i]+=2,col[j]+=2; } if(col[i]>=1 && col[j]>=1) { col[i]--,col[j]--; dfs(dep+1,num+6); col[i]++,col[j]++; } } dfs(dep+1,num+4); col[k]=4; }//四带x k=1; while(k<=13) { if(col[k]>=3) break; k++; } if(k<=13) { col[k]-=3; for(int i=0;i<=13;i++) { if(col[i]) { col[i]--; dfs(dep+1,num+4); col[i]++; } if(col[i]>=2) { col[i]-=2; dfs(dep+1,num+5); col[i]+=2; } } dfs(dep+1,num+3); col[k]+=3; }//三带x int tmp=0; for(int i=0;i<=13;i++) if(col[i]) tmp++;//单种牌处理 dfs(dep+tmp,n); } int main() { scanf("%d%d",&T,&n); while(T--) { ans=n; memset(col,0,sizeof(col)); for(int i=1;i<=n;i++) { int x,y; scanf("%d%d",&x,&y); col[x]++; } dfs(0,0); printf("%d\n",ans); } return 0; } ```