现在的位置: 首页 > 综合 > 正文

UVA – 11210 Chinese Mahjong(注意暴力搜索时排除排列重复搜索)

2018年03月17日 ⁄ 综合 ⁄ 共 1367字 ⁄ 字号 评论关闭

为了使得在暴力dfs判断选完将之后剩下的牌是否构成刻子和顺子;要用now【34】数组记录每张牌的个数,并且一直从有牌的内个最小编号牌判断其是否属于某个刻子或顺子;而且他所属顺子一定以他为最小值;

#include <cstdio>
#include <cstring>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
const int maxn = 136 + 10;

const char* mahjong[]={
"1T","2T","3T","4T","5T","6T","7T","8T","9T",
"1S","2S","3S","4S","5S","6S","7S","8S","9S",
"1W","2W","3W","4W","5W","6W","7W","8W","9W",
 "DONG", "NAN", "XI", "BEI",
 "ZHONG", "FA", "BAI"
};
int ID(char* s){
  for(int i=0;i<34;i++){
    if(strcmp(mahjong[i],s)==0) return i;
  }
}
char str[100];
int yuan[14],now[34];
bool dfs(int d,int num){
  if(num==0) return true;
  int nd = d;
  for(int i=d;i<34;i++){
    if(now[i]>=1){
        nd = i;
        break;
    }
  }
  if(now[nd] >=3){
     now[nd]-=3;
     if(dfs(nd,num-3)) return true;
     now[nd]+=3;
  }
  if(nd<27&&nd%9<=6&&now[nd]>=1&&now[nd+1]>=1&&now[nd+2]>=1){
     now[nd]--; now[nd+1]--; now[nd+2]--;
     if(dfs(nd,num-3)) return true;
     now[nd]++; now[nd+1]++; now[nd+2]++;
  }
  return false;
}
bool check(){
  for(int i=0;i<34;i++){
    if(now[i]>=2){
        now[i] -= 2;
        if(dfs(0,12)) return true;
        now[i] += 2;
    }
  }
  return false;
}
int main()
{
    int kase=1;
    while(scanf("%s",str)==1){
      if(str[0]=='0') break;
      yuan[0] = ID(str);
      for(int i=1;i<13;i++){
        scanf("%s",str);
        yuan[i]=ID(str);
      }
      printf("Case %d:",kase++);
      int tot=0;
      for(int i=0;i<34;i++){
        memset(now,0,sizeof(now));
        for(int j=0;j<13;j++) now[yuan[j]]++;
        if(now[i]>=4) continue;
        now[i]++;
        if(check()){
            tot++;  printf(" %s",mahjong[i]);
        }
      }
      if(!tot) printf(" Not ready\n");
      else printf("\n");
    }
    return 0;
}

抱歉!评论已关闭.