11210 - Chinese Mahjong【暴力、模拟、减枝】

36 篇文章 0 订阅
33 篇文章 0 订阅

模拟题,需要注意2个地方,一个是一种牌只有4张,意外就是 风 牌 和 箭牌 不能组成顺子

#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn = 100;
int Num[maxn];
int Card[20];
int _Card[20];
int vis[20];   //记录
vector<int>ans;
int ID[maxn] = {1,2,3,4,5,6,7,8,9,
                11,12,13,14,15,16,17,18,19,
                21,22,23,24,25,26,27,28,29,
                31,32,33,34,
                41,42,43}; //34
void init(){
    memset(Num,0,sizeof(Num));
    for(int i = 0; i < 34; i++)
        Num[ID[i]] = 4;
}
int GetId(char *str){
    if(str[1] == 'T')
        return str[0] - '0';        //1 ~ 9
    else if(str[1] == 'S')
        return str[0] - '0' + 10;   //11 ~ 19
    else if(str[1] == 'W')
        return str[0] - '0' + 20;   //21 ~ 29
    else if(strcmp(str,"DONG") == 0)//31 ~ 34
        return 31;
    else if(strcmp(str,"NAN") == 0)
        return 32;
    else if(strcmp(str,"XI") == 0)
        return 33;
    else if(strcmp(str,"BEI") == 0)
        return 34;
    else if(strcmp(str,"ZHONG") == 0)    //41 ~ 43;
        return 41;
    else if(strcmp(str,"FA") == 0)
        return 42;
    else if(strcmp(str,"BAI") == 0)
        return 43;
}
void debug(int array[],int n){
    for(int i = 0; i < n; i++)
        printf("%d ,",array[i]);
    puts("");
}
bool dfs(int v){
    int ok = 1;
    //judge
    for(int i = 0; i < 14; i++)
        if(!vis[i]) {ok = 0; break;}
    if(ok)
        return true;
    for(int i = v; i < 14; i++)if(!vis[i]){
        vis[i] = 1;
        for(int j = i + 1; j < 14; j++) if(!vis[j]){
            vis[j] = 1;
            for(int k = j + 1; k < 14; k++) if(!vis[k]){
                vis[k] = 1;
                if(_Card[i] == _Card[j] && _Card[j] == _Card[k]){
                    int x;
                    for(x = 0; x < 14; x++) if(!vis[x]) break;
                    if(dfs(x))
                        return true;
                }
                //只有T S W 1 ~ 29才形成顺子
                else if(_Card[i] < 31 && _Card[i]  + 1 == _Card[j] && _Card[j] + 1 == _Card[k]){
                    int x;
                    for(x = 0; x < 14; x++) if(!vis[x]) break;
                    if(dfs(x))
                        return true;
                }
                vis[k] = 0;
            }
            vis[j] = 0;
        }
        vis[i] = 0;
    }
    return false;
}
int main(){
    char str[10];
    int Case = 1;
    //freopen("D:\\1.txt","w",stdout);
    while(scanf("%s",str) != EOF){
        init(); //初始化牌的数量
        ans.clear();
        if(strcmp(str,"0") == 0)
            break;
        Card[0] = GetId(str);
        for(int i = 1; i < 13; i++){
            scanf("%s",str);
            Card[i] = GetId(str);
        }
        for(int i = 0; i < 13; i++){
            Num[Card[i]] --;
        }
        for(int i = 0; i < 34; i++){
            int e = Num[ID[i]];
            //printf("[%d]",ID[i]);
            //printf("%d\n",e);
            if(e){
                memcpy(_Card,Card,sizeof(Card));
                _Card[13] = ID[i];
                sort(_Card,_Card + 14);
                //debug(_Card,14);
                //每次选2个一样的
                for(int j = 0; j < 13; j++){
                    if(_Card[j] == _Card[j + 1]){   //选牌为将
                        memset(vis,0,sizeof(vis));
                        vis[j] = 1;
                        vis[j + 1] = 1;
                        if(dfs(0)){
                            ans.push_back(ID[i]);
                            break;
                        }
                    }
                }
            }
        }
        printf("Case %d:",Case++);
        sort(ans.begin(),ans.end());
        if(ans.size() == 0)
            printf(" Not ready");
        for(int i = 0; i < ans.size(); i++){
            printf(" ");
            if(ans[i] >= 1 && ans[i] <= 9){
                printf("%dT",ans[i]);
            }
            else if(ans[i] >= 11 && ans[i] <= 19){
                printf("%dS",ans[i] % 10);
            }
            else if(ans[i] >= 21 && ans[i] <= 29){
                printf("%dW",ans[i] % 20);
            }
            else if(ans[i] == 31){
                printf("DONG");
            }
            else if(ans[i] == 32){
                printf("NAN");
            }
            else if(ans[i] == 33){
                printf("XI");
            }
            else if(ans[i] == 34){
                printf("BEI");
            }
            else if(ans[i] == 41){
                printf("ZHONG");
            }
            else if(ans[i] == 42){
                printf("FA");
            }
            else if(ans[i] == 43){
                printf("BAI");
            }
        }
        puts("");
    }
    return 0;
}
/*
1S 1S
2S 2S 2S
3S 3S 3S
7S 8S 9S
FA FA
*/

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值