题解
2023-03-11 20:28:01
发布于:上海
#include<bits/stdc++.h>
using namespace std;
inline int rd(){
int x=0,f=1;char c=getchar();
while(!isdigit(c)){if(c=='-') f^=1;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return f?x:-x;
}
int T,n,ans,a[30];
void dfs(int d){
if(d>=ans) return;
//1. 顺子(5)
for(int l=3;l<=10;++l){
if(!a[l]) continue;
int r=l+1;
while(r<=13&&a[r]) ++r;--r;
if(r13&&a[1]) ++r;
//最长[l,r]
if(r-l+1<5) continue;
for(int i=l+4;i<=r;++i){
for(int j=l;j<=i;++j)
if(j<=13) --a[j];
else --a[1];
dfs(d+1);
for(int j=l;j<=i;++j)
if(j<=13) ++a[j];
else ++a[1];
}
}
//2. 双顺子(3)
for(int l=3;l<=12;++l){
if(a[l]<2) continue;
int r=l+1;
while(r<=13&&a[r]>=2) ++r;--r;
if(r13&&a[1]>=2) ++r;
if(r-l+1<3) continue;
for(int i=l+2;i<=r;++i){
for(int j=l;j<=i;++j)
if(j<=13) a[j]-=2;
else a[1]-=2;
dfs(d+1);
for(int j=l;j<=i;++j)
if(j<=13) a[j]+=2;
else a[1]+=2;
}
}
//3. 三顺子(2)
for(int l=3;l<=13;++l){
if(a[l]<3) continue;
int r=l+1;
while(r<=13&&a[r]>=3) ++r;--r;
if(r13&&a[1]>=3) ++r;
if(r-l+1<2) continue;
for(int i=l+1;i<=r;++i){
for(int j=l;j<=i;++j)
if(j<=13) a[j]-=3;
else a[1]-=3;
dfs(d+1);
for(int j=l;j<=i;++j)
if(j<=13) a[j]+=3;
else a[1]+=3;
}
}
//4. 四带二
for(int i=1;i<=13;++i){
if(a[i]<4) continue;
a[i]=0;
//4.1 带两张零牌 / 一个对子
for(int j=1;j<=14;++j){
if(!a[j]) continue;
--a[j];
for(int k=1;k<=14;++k){
if(!a[k]) continue;
--a[k],dfs(d+1),++a[k];
}
++a[j];
}
//4.2 带两个对子
for(int j=1;j<=13;++j){
if(a[j]<2) continue;
a[j]-=2;
for(int k=1;k<=13;++k){
if(a[k]<2) continue;
a[k]-=2,dfs(d+1),a[k]+=2;
}
a[j]+=2;
}
a[i]=4;
}
//5. 三带二 / 三带一
for(int i=1;i<=13;++i){
if(a[i]<3) continue;
a[i]-=3;
for(int j=1;j<=13;++j){
if(a[j]<2||ij) continue;
a[j]-=2,dfs(d+1),a[j]+=2;
}
for(int j=1;j<=14;++j){
if(!a[j]||i==j) continue;
--a[j],dfs(d+1),++a[j];
}
a[i]+=3;
}
//6. 零牌
for(int i=1;i<=14;++i)
if(a[i]) ++d;
ans=min(ans,d);
}
int main(){
T=rd(),n=rd();
while(T--){
ans=0x7fffffff;
memset(a,0,sizeof(a));
for(int i=1,x,y;i<=n;++i){
x=rd(),y=rd();
x?++a[x]:++a[14];
}
dfs(0);
printf("%d\n",ans);
}
return 0;
}
这里空空如也
有帮助,赞一个