【NOIP 2015】 D1 T3 斗地主

来源:互联网 发布:阿里云香港服务器速度 编辑:程序博客网 时间:2024/06/05 07:52

【问题描述】
这里写图片描述
这里写图片描述


【输入格式】
这里写图片描述
【输出格式】
共 T 行,每行一个整数表示打光第 i 组手牌的最少次数。


这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述


【防爆零代码】
  枚举手牌组数少的时候打光的所有可能性(30分)

#include<iostream>int x[20001],y[20001];using namespace std;int main(){    freopen("landlords.in","r",stdin);    freopen("landlords.out","w",stdout);    int t,n;    cin>>t>>n;    for(int i=1;i<=t;i++)    {        for(int i=1;i<=n;i++)          cin>>x[i]>>y[i];        if(n==1)           cout<<"1"<<endl;        if(n==2)        {        if(x[1]==x[2]) cout<<"1"<<endl;        else cout<<"2"<<endl;        }        if(n==3)        {            if(x[1]==x[2]&&x[1]==x[3])  cout<<"1"<<endl;            else if(x[1]==x[2]||x[1]==x[3]||x[2]==x[3])  cout<<"2"<<endl;            else cout<<"3"<<endl;        }        if(n==4)        {            if(x[1]==x[2]&&x[1]==x[3]&&x[1]==x[4]) cout<<"1"<<endl;            else            if(x[1]==x[2]&&x[2]==x[3])             cout<<1<<endl;            else            if(x[1]==x[2]&&x[2]==x[4])             cout<<1<<endl;            else            if(x[1]==x[3]&&x[3]==x[4])             cout<<1<<endl;            else            if(x[2]==x[3]&&x[3]==x[4])             cout<<1<<endl;            else            if(x[1]==x[2]&&x[3]==x[4])             cout<<2<<endl;            else            if(x[1]==x[3]&&x[2]==x[4])             cout<<2<<endl;            else            if(x[1]==x[4]&&x[2]==x[3])             cout<<2<<endl;            else            if(x[1]==x[2])             cout<<3<<endl;            else            if(x[1]==x[3])             cout<<3<<endl;            else            if(x[1]==x[4])             cout<<3<<endl;            else            if(x[2]==x[3])             cout<<3<<endl;             else            if(x[2]==x[4])             cout<<3<<endl;             else            if(x[3]==x[4])             cout<<3<<endl;             else             cout<<4<<endl;        }    }}

【正解】
1.花色在本题中无用
2.出牌顺序除了顺子之外对打完手牌次数无影响
3.如果不打顺子,打完手牌次数一定,所以dfs搜索出单顺子,双顺子,三顺子后的总步数,然后更新答案
4.王要单独出

代码:

#include<iostream>#include<cstdio>#include<cstring>int a[15],num[15];int n,t,ans;using namespace std;int chupai(){    memset(num,0,sizeof(num));    for(int i=0;i<=13;i++)        num[a[i]]++;    int tot=0;    while(num[4]&&num[2]>1)    {        num[4]--;        num[2]-= 2;        tot++;    }    while(num[4]&&num[1]>1)    {        num[4]--;        num[1]-=2;        tot++;    }    while(num[4]&&num[2])    {        num[4]--;        num[2]--;        tot++;    }    while(num[3] && num[2])    {        num[3]--;        num[2]--;        tot++;    }    while(num[3]&&num[1])    {        num[3]--;        num[1]--;        tot++;    }    return tot+num[1]+num[2]+num[3]+num[4];}void dfs(int step){    if(step>=ans)    {        return;    }    int temp=chupai();    if(temp+step<ans)      ans=temp+step;    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(step+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(step+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(step+1);                for(int k=i;k<=j2;k++)                  a[k]++;            }        }    }}int main(){    freopen("landlords.in","r",stdin);    freopen("landlords.out","w",stdout);    scanf("%d%d",&t,&n);    while(t--)    {        memset(a,0,sizeof(a));        for(int i=1;i<=n;i++)        {            int x,y;            scanf("%d%d",&x,&y);            if(x==1)//转换A               x=13;            else            {                if(x!=0)                  x--;            }                a[x]++;        }        ans=9999999;        dfs(0);        printf("%d\n",ans);    }    return 0;}
0 0
原创粉丝点击