Uva-11210-Chinese Mahjong

这个题是对麻将的一个模拟,要求求出所有可以“听"牌的可能,其实可以枚举所有的牌然后进行搜索看这张牌是否可以成为听牌,而如果拥有着张牌后能够成功的和牌,那么就说明这张牌能够成为听牌。

再添加某张牌后,选一个多余或等于2张的牌出来,然后进行进一步搜索判断这张牌是否可以成为听牌。

其中还需要注意的是同种牌不能超过4张。

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
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 m[20],mm[50];
int GetIndex(char *str)
{
    for(int i=0;i<34;i++)
	if(!strcmp(mahjong[i],str))
	    return i;
}
bool DFSS(int res)
{
    if(!res)
	return true;
    for(int i=0;i<34;i++)
	if(mm[i]>=3)
	{
	    mm[i]-=3;
	    if(DFSS(res-3))
		return true;
	    mm[i]+=3;
	}
    for(int i=0;i<27;i++)
    {
	if(i%9<=6&&mm[i]&&mm[i+1]&&mm[i+2])
	{
	    mm[i]--;mm[i+1]--;mm[i+2]--;
	    if(DFSS(res-3))
		return true;
	    mm[i]++;mm[i+1]++;mm[i+2]++;
	}
    }
    return false;
}
bool DFS()
{
    for(int i=0;i<34;i++)
    {
	if(mm[i]>=2)
	{
	    mm[i]-=2;
	    if(DFSS(12))
		return true;
	    mm[i]+=2;
	}
    }
    return false;
}
	
int main()
{
    char str[100];
    int mmas=1;
    while(scanf("%s",str)!=EOF)
    {
	if(str[0]=='0')
	    break;
	printf("Case %d:",mmas++);
	m[0]=GetIndex(str);
	for(int i=1;i<13;i++)
	{
	    scanf("%s",str);
	    m[i]=GetIndex(str);
	}
	bool getans=false;
	for(int i=0;i<34;i++)
	{
	    memset(mm,0,sizeof(mm));
	    for(int j=0;j<13;j++)
		mm[m[j]]++;
	    if(mm[i]>=4)
		continue;
	    mm[i]++;
	    if(DFS())
	    {
		getans=true;
		printf(" %s",mahjong[i]);
	    }
	    mm[i]--;
	}
	if(!getans)
	    printf(" Not ready");
	printf("\n");

    }
    return 0;
}


你可能感兴趣的:(模拟,DFS)