UVa 11210 - Chinese Mahjong

来源:互联网 发布:知乎 德军 编辑:程序博客网 时间:2024/05/21 18:31

題目:打麻將,簡化后的最後只可以是一個對子加上多個三元組(連續或者相同),

            現在已知手牌,問需要什麼才能和,或者沒法和。

分析:搜索。利用對子和三元組進行dfs。

            這裡將數據分成四組,前三組(餅、條、萬)相同,最後一組只能相同的組合;

            搜索時使用兩個變量two、three記錄組合個數,用來判斷合法(剪枝);

            每次搜完一行跳轉到下一行(我這個代碼效率不太高o(╯□╰)o);

說明:網好差╮(╯▽╰)╭。

#include <stdlib.h>#include <stdio.h>char tile_name[4][10][10] = {    "", "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 tile[4][10];int tile_line[4];int get_input(char str[]){    if (str[0] >= '1' && str[0] <= '9') {        if (str[1] == 'T') {            tile[0][str[0]-'0'] ++;            tile_line[0] ++;        }else if (str[1] == 'S') {            tile[1][str[0]-'0'] ++;            tile_line[1] ++;        }else if (str[1] == 'W') {            tile[2][str[0]-'0'] ++;            tile_line[2] ++;        }    }else {        if (str[0] == 'D') {            tile[3][1] ++;        }else if (str[0] == 'N') {            tile[3][2] ++;        }else if (str[0] == 'X') {            tile[3][3] ++;        }else if (str[0] == 'B' && str[1] == 'E') {            tile[3][4] ++;        }else if (str[0] == 'Z') {            tile[3][5] ++;        }else if (str[0] == 'F') {            tile[3][6] ++;        }else if (str[0] == 'B' && str[1] == 'A') {            tile[3][7] ++;        }        tile_line[3] ++;    }}int dfs(int k, int two, int three){    if (two > 1) {        return 0;    }    if (k == 3) {        for (int i = 1; i <= 7; ++ i) {            if (tile[k][i] == 2) {                two ++;            }else if (tile[k][i] == 3) {                three ++;            }        }        return (three == 4 && two == 1);    }else if (!tile_line[k]) { // 本行沒有進入下一行         return dfs(k+1, two, three);    }else {        int ans;        for (int i = 1; i <= 9; ++ i) {            if (tile[k][i] >= 2) { // 對子                 tile[k][i] -= 2;                tile_line[k] -= 2;                ans = dfs(k, two+1, three);                tile_line[k] += 2;                tile[k][i] += 2;                if (ans == 1) {                    return 1;                }            }            if (tile[k][i] >= 3) { // 碰                 tile[k][i] -= 3;                tile_line[k] -= 3;                ans = dfs(k, two, three+1);                tile_line[k] += 3;                tile[k][i] += 3;                if (ans == 1) {                    return 1;                }            }            for (int j = -2; j <= 0; ++ j) { // 順                 if (i+j >= 1 && i+j+2 <= 9) {                    if (tile[k][i+j] && tile[k][i+j+1] && tile[k][i+j+2]) {                        tile[k][i+j] --;                        tile[k][i+j+1] --;                        tile[k][i+j+2] --;                        tile_line[k] -= 3;                        ans = dfs(k, two, three+1);                        tile_line[k] += 3;                        tile[k][i+j+2] ++;                        tile[k][i+j+1] ++;                        tile[k][i+j] ++;                        if (ans == 1) {                            return 1;                        }                    }                }            }        }        return 0;    }}int main(){    char buf[10], cases = 1;    while (~scanf("%s",buf) && buf[0] != '0') {        for (int i = 0; i < 4; ++ i) {            for (int j = 1; j <= 9; ++ j) {                tile[i][j] = 0;            }            tile_line[i] = 0;        }        get_input(buf);        for (int i = 0; i < 12; ++ i) {            scanf("%s",buf);            get_input(buf);        }                printf("Case %d:",cases ++);        int count = 0;        for (int i = 0; i < 4; ++ i) {            for (int j = 1; j <= 9; ++ j) {                if (tile[i][j] < 4) {                    tile[i][j] ++;                    tile_line[i] ++;                    if (dfs(0, 0, 0)) {                        printf(" %s",tile_name[i][j]);                        count ++;                    }                    tile_line[i] --;                    tile[i][j] --;                }            }        }        if (!count) {            printf(" Not ready");        }        puts("");    }    return 0;}


0 0
原创粉丝点击