您的位置:首页 > 其它

NOIP 2015 斗地主

2017-10-03 21:41 204 查看

题目

分析:

这道题要用搜索做,差不多按照题目意思打代码就是的了。不过有些地方还是得相同才比较好打。就直接在代码中解释啦。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int t,n,a[20],c[5],ans;
inline int read(){
int x=0,w=1;char ch=0;
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') w=-1,ch=getchar();
while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
return x*w;
}
inline int work(){
memset(c,0,sizeof(c));//记得要清0
for(int i=0;i<=13;i++) c[a[i]]++;//c数组中是指牌数为1,2,3,4的种类有几个。
int tot=0;
while(c[4]&&c[2]>1) c[4]--,c[2]-=2,tot++;//处理4带两对
while(c[4]&&c[1]>1) c[4]--,c[1]-=2,tot++;//处理4带两个单
while(c[4]&&c[2]) c[4]--,c[2]--,tot++;//处理4带一对
while(c[3]&&c[1]) c[3]--,c[1]--,tot++;//处理3带1
while(c[3]&&c[2]) c[3]--,c[2]--,tot++;//处理3带一对
return tot+c[1]+c[2]+c[3]+c[4];
}
void dfs(int now){
if(now>ans) return ;
int temp=work();
if(temp+now<ans) ans=temp+now;
for(int i=2;i<=13;i++){//三顺
int j=i;
while(a[j]>=3) j++;
if(j-i>=2){
for(int j2=i+1;j2<=j-1;j2++){
for(int k=i;k<=j2;k++) a[k]-=3;
dfs(now+1);
for(int k=i;k<=j2;k++) a[k]+=3;
}
}
}
for(int i=2;i<=13;i++){//双顺
int j=i;
while(a[j]>=2) j++;
if(j-i>=3){
for(int j2=i+2;j2<=j-1;j2++){
for(int k=i;k<=j2;k++) a[k]-=2;
dfs(now+1);
for(int k=i;k<=j2;k++) a[k]+=2;
}
}
}
for(int i=2;i<=13;i++){//单顺
int j=i;
while(a[j]>=1) j++;
if(j-i>=5){
for(int j2=i+4;j2<=j-1;j2++){
for(int k=i;k<=j2;k++) a[k]--;
dfs(now+1);
for(int k=i;k<=j2;k++) a[k]++;
}
}
}
}
int main(){
freopen("2668.in","r",stdin);
freopen("2668.out","w",stdout);
t=read();n=read();
for(int k=1;k<=t;k++){
memset(a,0,sizeof(a));//记得要请0
for(int i=1;i<=n;i++){
int x=read(),y=read();
if(x==1) x=13;//把A储存为13
else if(x) x--;//把小王用0存,大王用1存,其它在各自的基础上-1
a[x]++;
}
ans=1e9;
dfs(0);
printf("%d\n",ans);//输出答案
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  搜索