UVa --- 11210 中国麻将【暴力深搜】

来源:互联网 发布:布罗代尔 知乎 编辑:程序博客网 时间:2024/05/10 09:40

传送门
//考虑到UVa和LA有一点不熟悉, 我就都是咋VJ上交的题, 链接也是.
//这些题的做法就不说了, 我是在白书的基础上加深了点理解自己写的. 代码解释也是直接写在代码中的.
//大概思想就是枚举每一种牌,检查是否有了这张牌后可以”和”. 所以直接深搜即可. 拿来练练代码力. 其实后面做了一道hdu的跟这道很像, 但是hdu的那道更难一点, 并且数据更强一些. 这都是后面再加了一些剪枝的, 当然这道题由于数据问题, 不加剪枝也能过, 但是hdu的就过不了. 具体解法可以参照我的那一篇博客

AC Code

const int maxn = 100+5;int cas=1;char *Ma[] = { "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" };inline int change(char *s){    for(int i=0;i<34;i++){        if(strcmp(s,Ma[i]) == 0)            return i;    }}bool check(int x)    //判断是否可以组成顺子.{    if(x>=0 && x<=6) return true;    else if(x>=9 && x<= 15) return true;    else if(x>=18 && x <= 24) return true;    else return false;}int c[maxn];inline bool dfs(int deep){    if(deep >=4) return true;    int flag = 0;    for(int i=0;i<34;i++){        int ff = 0;        if(c[i]>=3){            ff++;            c[i] -= 3;            if(dfs(deep+1)) return true;            c[i] += 3;        }        if(check(i) && c[i] > 0 && c[i+1] > 0 && c[i+2] > 0){            ff++;            c[i]--; c[i+1]--; c[i+2]--;            if(dfs(deep+1)) return true;            c[i]++; c[i+1]++; c[i+2]++;        }        if(c[i] && !ff) return false;        if(c[i]) break;    }    return false;}inline bool check1(){    for(int i=0;i<34;i++){        if(c[i]>=2) {            c[i] -= 2;            if(dfs(0)) return true;            c[i] += 2;        }    }    return false;}int ans[maxn];void solve(){    char s[10]; int mj[maxn];    while(~scanf("%s",s)){        if(s[0] == '0') break;        mj[0] = change(s);        for(int i=1;i<13;i++){            scanf("%s",s);            mj[i] = change(s);        }        bool flag = 0; int cnt = 0;        for(int i=0;i<34;i++){            Fill(c,0);            for(int j=0;j<13;j++) c[mj[j]]++;            if(c[i]>=4) continue;            c[i]++;            if(check1()) {                flag = 1;                ans[cnt++] = i;            }        }        printf("Case %d: ",cas++);        if(!flag) puts("Not ready");        else{            for(int i=0;i<cnt;i++){                printf("%s%c",Ma[ans[i]],i==cnt-1?'\n':' ');            }        }    }}
原创粉丝点击