hdu4431Mahjong

题目大意就是给出13张牌问你再拿一张什么牌能够糊牌。

枚举每一钟牌,然后根据题目要求模拟出能否糊牌。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <map>
#define MAXN 40

using namespace std;
int cnt[MAXN],temp[MAXN],ans[MAXN];
int total;
char s[20];
map<string,int>mp;  

void init()  
{  
    mp["1m"]=1; mp["1s"]=11; mp["1p"]=21;  
    mp["2m"]=2; mp["2s"]=12; mp["2p"]=22;  
    mp["3m"]=3; mp["3s"]=13; mp["3p"]=23;  
    mp["4m"]=4; mp["4s"]=14; mp["4p"]=24;  
    mp["5m"]=5; mp["5s"]=15; mp["5p"]=25;  
    mp["6m"]=6; mp["6s"]=16; mp["6p"]=26;  
    mp["7m"]=7; mp["7s"]=17; mp["7p"]=27;  
    mp["8m"]=8; mp["8s"]=18; mp["8p"]=28;  
    mp["9m"]=9; mp["9s"]=19; mp["9p"]=29;  
    mp["1c"]=31;mp["2c"]=32; mp["3c"]=33;  
    mp["4c"]=34;mp["5c"]=35; mp["6c"]=36;  
    mp["7c"]=37;  
}
bool  ok()
{
      for (int i=1;i<38;++i)if(cnt[i]>4) return false;
      return true;
}
bool judge0()  
{  
    for(int i=1;i<38;i++) temp[i]=cnt[i];  
    for(int i=1;i<38;i++)  
    {  
        if(temp[i]>=3) temp[i]-=3;  
        if(temp[i])  
        {  
            if(i>30) return 0;                  // don't chose c
            if(temp[i+1]<temp[i]||temp[i+2]<temp[i]) return false;  
            else temp[i+1]-=temp[i],temp[i+2]-=temp[i],temp[i]=0;  
        }  
    }  
    return true;  
}  
bool  judge1()
{
      for (int i=1;i<38;++i)
      if (cnt[i]>=2)
      {
          cnt[i]-=2;
          if (judge0()){ cnt[i]+=2;return true;}
          cnt[i]+=2;           
      }
      return false;
}
bool  judge2()// 7 pair
{
      int tot=0;
      for(int i=1;i<38;++i)
        if (cnt[i]==2) tot+=1;
      return (tot==7);
} 
bool  judge3()    //1 piar+12
{
      int a=0,b=0;
      for (int i=0;i<3;++i)
      {
          if(cnt[i*10+1]==1) a++;
          if(cnt[i*10+1]==2) b++;
          if(cnt[i*10+9]==1) a++;
          if(cnt[i*10+9]==2) b++;
      }
      for (int i=31;i<38;++i)
      {
          if(cnt[i]==1) a++;
          if(cnt[i]==2) b++;
      }
      return (a==12&&b==1);
}
void  print(int x){
      char c;
      printf(" %d",x%10);
      if (x<10) c='m';else
      if (x<20) c='s';else
      if (x<30) c='p';else
      c='c';
      printf("%c",c);
}
void  work()
{
      memset(cnt,0,sizeof(cnt));
      for (int i=0 ; i < 13;++i) 
          scanf("%s",s),cnt[mp[s]]++;
      total=0;
      for (int i=1; i< 38; ++i)
      if (i%10!=0)
      {
         cnt[i]++;
         if (ok())
         {
            if (judge1() || judge2() || judge3())
               ans[total++]=i;
         }
         cnt[i]--;
      }
      if (total){
          cout<<total;
          for (int i=0; i< total ;++i) print(ans[i]);
          cout<<endl;
      } else
       cout<<"Nooten"<<endl;
}
int main()
{
    int test=0;
    cin>>test;
    init();
    while (test--) work();
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值