zoukankan      html  css  js  c++  java
  • UVA 11210 Chinese Mahjong

    UVA_11210

    一开始觉得这个题目比较麻烦便有点胆怯,后来鼓起勇气开始编之后,发现其实只要把每种情况考虑周全并且回溯得当的话还是不难的。

    深搜中间之所以把eye设成全局变量并且放在return语句后面进行回溯,是因为我们大体可以把牌分4类,4类中最多只有一个eye,并且如果当前某一类在占用一个eye之后使这一类成为了符合要求的牌,那么这一类不占一个eye的话就一定是不符合要求的(这类牌的张数决定的)。

    我的程序里面的prepare()函数是可以不用的,当时为了刷排名才刻意加了一个这样的函数。

    另外,不知道外国人看到刘汝佳的下面这句话时,不知道会不会求助于Google呢……

        To who knows more about Mahjong: don’t consider special winning hands such as ‘七对子’.

    #include<stdio.h>
    #include
    <string.h>
    #include
    <ctype.h>
    int p[3][15],f[10],eye;
    char ap[]={'T','S','W'},b[10];
    char af[][10]={"DONG","NAN","XI","BEI","ZHONG","FA","BAI"};
    int dfs_f(int cur,int e)
    {
    int i,ok;
    for(i=cur;f[i]==0&&i<7;i++);
    if(i==7)
    return 1;
    if(f[i]==4)
    return 0;
    if(f[i]==3)
    {
    f[i]
    -=3;
    ok
    =dfs_f(i,e);
    f[i]
    +=3;
    if(ok)
    return 1;
    }
    else if(f[i]==2)
    {
    if(e)
    return 0;
    else
    {
    f[i]
    -=2;
    eye
    =1;
    ok
    =dfs_f(i,eye);
    f[i]
    +=2;
    if(ok)
    return 1;
    eye
    =0;
    }
    }
    return 0;
    }
    int dfs_p(int s,int cur,int e)
    {
    int i,j,ok;
    for(i=cur;p[s][i]==0&&i<9;i++);
    if(i==9)
    return 1;
    if(p[s][i]>=3)
    {
    p[s][i]
    -=3;
    ok
    =dfs_p(s,i,e);
    p[s][i]
    +=3;
    if(ok)
    return 1;
    }
    if(p[s][i]>=2&&!e)
    {
    p[s][i]
    -=2;
    eye
    =1;
    ok
    =dfs_p(s,i,eye);
    p[s][i]
    +=2;
    if(ok)
    return 1;
    eye
    =0;
    }
    if(i<7&&p[s][i+1]&&p[s][i+2])
    {
    p[s][i]
    -=1;
    p[s][i
    +1]-=1;
    p[s][i
    +2]-=1;
    ok
    =dfs_p(s,i,e);
    p[s][i]
    +=1;
    p[s][i
    +1]+=1;
    p[s][i
    +2]+=1;
    if(ok)
    return 1;
    }
    return 0;
    }
    int judge()
    {
    int i,eye=0;
    if(!dfs_f(0,eye))
    return 0;
    for(i=0;i<3;i++)
    if(!dfs_p(i,0,eye))
    return 0;
    return 1;
    }
    int init()
    {
    int i,j,k;
    for(i=0;i<13;i++)
    {
    scanf(
    "%s",b);
    if(b[0]=='0')
    return 0;
    if(isdigit(b[0]))
    {
    k
    =b[0]-'1';
    for(j=0;;j++)
    if(ap[j]==b[1])
    break;
    p[j][k]
    ++;
    }
    else
    {
    for(j=0;;j++)
    if(strcmp(af[j],b)==0)
    break;
    f[j]
    ++;
    }
    }
    return 1;
    }
    int prepare()
    {
    int i,j;
    for(i=0;i<7;i++)
    if(f[i]==4||f[i]==1)
    return 0;
    for(i=0;i<3;i++)
    for(j=0;j<9;j++)
    if(p[i][j]==1)
    {
    if(j==0)
    {
    if(!p[i][j+1])
    return 0;
    }
    else if(j==8)
    {
    if(!p[i][j-1])
    return 0;
    }
    else
    {
    if(!p[i][j-1]&&!p[i][j+1])
    return 0;
    }
    }
    return 1;
    }
    int main()
    {
    int i,j,k,t,ok;
    t
    =0;
    while(1)
    {
    memset(p,
    0,sizeof(p));
    memset(f,
    0,sizeof(f));
    if(!init())
    break;
    printf(
    "Case %d:",++t);
    ok
    =0;
    for(i=0;i<3;i++)
    for(j=0;j<9;j++)
    if(p[i][j]!=4)
    {
    p[i][j]
    ++;
    if(prepare()&&judge())
    {
    ok
    =1;
    printf(
    " %d%c",j+1,ap[i]);
    }
    p[i][j]
    --;
    }
    for(i=0;i<7;i++)
    if(f[i]!=4)
    {
    f[i]
    ++;
    if(prepare()&&judge())
    {
    ok
    =1;
    printf(
    " %s",af[i]);
    }
    f[i]
    --;
    }
    if(!ok)
    printf(
    " Not ready\n");
    else
    printf(
    "\n");
    }
    return 0;
    }

      

  • 相关阅读:
    C# Arrays
    C# 类 (12)
    C# 类 (11)
    C# 类 (10)
    常用的HDFS操作
    Java StringTokenizer 类使用方法
    常用HBase操作
    常用Linux命令
    彻底关闭Windows10的更新
    如何将百度坐标转换为国家2000(或WGS84)坐标系?
  • 原文地址:https://www.cnblogs.com/staginner/p/2181581.html
Copyright © 2011-2022 走看看