洛谷 P2668 斗地主
P2668 斗地主
统计单牌和对牌的数量
然后
凑顺子,能凑就凑
还有四带balabala和三带balabala
1 #include<bits/stdc++.h> 2 using namespace std; 3 int n,t,s[15],ans,a,b; 4 5 inline void read(int &now) 6 { 7 char ch=getchar(); now=0; 8 while(ch>'9'||ch<'0') ch=getchar(); 9 while(ch>='0'&&ch<='9') now=now*10+ch-'0',ch=getchar(); 10 } 11 12 void dfs(int now) 13 { 14 if(now>ans) return; 15 int s1,s2,s3,s4,j; 16 s1=s2=s3=s4=0; 17 for(int i=1;i<=14;i++) if(s[i]==1) s1++; 18 for(int i=1;i<=14;i++) if(s[i]==2) s2++; 19 /*四带。。。*/ 20 for(int i=1;i<=14;i++) 21 { 22 if(s[i]==4) 23 { 24 s4++; 25 if(s1>=2) s1-=2; 26 else if(s2>=2) s2-=2; 27 else if(s2>=1) s2--; 28 } 29 } 30 /*三带。。。*/ 31 for(int i=1;i<=14;i++) 32 { 33 if(s[i]==3) 34 { 35 s3++; 36 if(s1>=1) s1--; 37 else if(s2>=1) s2--; 38 } 39 } 40 /*单顺子*/ 41 for(int i=1;i<=8;i++) 42 { 43 for(j=i;j<=12;j++) 44 { 45 s[j]--; 46 if(s[j]<0) break; 47 if(j-i>=4) dfs(now+1); 48 } 49 if(j==13) j--; 50 while(j>=i) s[j--]++; 51 } 52 /*双顺子*/ 53 for(int i=1;i<=10;i++) 54 { 55 for(j=i;j<=12;j++) 56 { 57 s[j]-=2; 58 if(s[j]<0) break; 59 if(j-i>=2) dfs(now+1); 60 } 61 if(j==13) j--; 62 while(j>=i) s[j--]+=2; 63 } 64 /*三顺子*/ 65 for(int i=1;i<=11;i++) 66 { 67 for(j=i;j<=12;j++) 68 { 69 s[j]-=3; 70 if(s[j]<0) break; 71 if(j-i>=1) dfs(now+1); 72 } 73 if(j==13) j--; 74 while(j>=i) s[j--]+=3; 75 } 76 ans=min(ans,now+s1+s2+s3+s4); 77 } 78 79 int main() 80 { 81 scanf("%d%d",&t,&n); 82 while(t--) 83 { 84 memset(s,0,sizeof(s)); 85 ans=23; 86 for(int i=1;i<=n;i++) 87 { 88 scanf("%d%d",&a,&b); 89 if(a==0) s[14]++; 90 if(a==1) s[12]++; 91 if(a==2) s[13]++; 92 if(a>=3) s[a-2]++; 93 } 94 dfs(0); 95 printf("%d\n",ans); 96 } 97 return 0; 98 }