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

hdu – 4431 – Mahjong – 模拟

2012年01月07日 ⁄ 综合 ⁄ 共 1976字 ⁄ 字号 评论关闭

就是给了13张牌。问增加哪些牌可以胡牌。

胡牌有以下几种情况:
1、一个对子 + 4组 3个相同的牌或者顺子。 只有m、s、p是可以构成顺子的。东西南北这样的牌没有顺子。
2、7个不同的对子。
3、1m,9m,1p,9p,1s,9s,1c,2c,3c,4c,5c,6c,7c. 这13种牌每种都有,而且仅有这13种牌。肯定是有一种2张。其他的1张。

首先是枚举18+7=34张牌,加进去构成14张牌,判断胡牌。
胡牌判断如下。
对于第一种情况:枚举每一个对子。然后按照顺序找3张相同或者顺子。如果有三种相同的,构成3张相同的。没有就看能不能和后面的构成顺子。一定要按照顺序从小到大找过去。 1c```7c只能构成3张一样的。然后判断是不是刚好找到4组。
对于第二种情况:就是要每一种牌的数量要么是0,要么是2,这样一定是7个不同的对子了。

对于第三种情况:就是要让这13种牌的数量不等于0,而且其他牌的数量为0;

#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
using namespace std;
int T, ans[300], sub, p[100], v[100];
char c, str[10];
const char * mah[] =
{
    "1m","2m","3m","4m","5m","6m","7m","8m","9m",
    "1s","2s","3s","4s","5s","6s","7s","8s","9s",
    "1p","2p","3p","4p","5p","6p","7p","8p","9p",
    "1c","2c","3c","4c","5c","6c","7c"
};
int ver[20] = {
    0,8,9,17,18,26,27,28,29,30,31,32,33
};
int convert(char * s){
    for(int i = 0; i < 34; i ++){
        if(strcmp(s,mah[i]) == 0)
            return i;
    }return -1;
}
// return false
bool three(int x){
    int ret = 0;
    int tmp[35] ;
    for(int i = 0; i < 34; i ++) tmp[i] = p[i];

    for(int i = 0; i <= 18; i += 9){
        for(int j = 0; j < 9; j ++){
            if(tmp[i + j] >= 3){
                tmp[i + j] -= 3;
                ret ++;
            }
            while(j + 2 < 9 && tmp[i + j] && tmp[i + j + 1] && tmp[i + j + 2]){
                tmp[i + j] --;
                tmp[i + j + 1] --;
                tmp[i + j + 2] --;
                ret ++;
            }
        }
    }
    for(int j = 0; j < 7; j ++){
        if(tmp [27 + j] >= 3){
            tmp[27 + j] -= 3;
            ret ++;
        }
    }
    if(ret == 4) return true;
    return false;
}
bool realcheck(){
    for(int i = 0; i < 34; i ++){
        if(p[i] >= 2){
            p[i] -= 2;
            if(three(0)){
                p[i] += 2;
                return true;
            }p[i] += 2;
        }
    }
    return false;
}
bool eyes(){
    for(int i = 0; i < 34; i ++){
        if(p[i] != 2 && p[i] != 0)
            return false;
    }
    return true;
}
bool spe(){
    for(int j = 0; j < 7; j ++)
        if(p[j + 27] == 0)
            return false;
    for(int i = 0; i <= 18; i += 9){
        if(p[i] == 0 || p[i + 8] == 0) return false;
        for(int j = 1; j < 8; j ++){
            if(p[i + j] != 0)
                return false;
        }
    }
    return true;
}
bool judge(){
    if(realcheck() || eyes() || spe()){
        return true;
    }return false;
}
int main(){
    scanf("%d", & T);
    while(T --){
        for(int i = 0; i < 13; i ++){
            scanf("%s", str);
            v[i] = convert(str);
        }
        memset(p, 0, sizeof(p));
        for(int i = 0; i < 13; i ++){
            p[v[i]] ++;
        }
        sub = 0;

        for(int i = 0; i < 34; i ++){
            if(p[i] < 4){
                p[i] ++;
                if(judge()){
                    ans[sub ++] = i;
                }
                p[i] --;
            }
        }
        if(sub >= 1){
            printf("%d", sub);
            for(int i = 0; i < sub; i ++){
                printf(" %s", mah[ans[i]]);
            }printf("\n");
        }else{
            printf("Nooten\n");
        }

    }
}

抱歉!评论已关闭.