程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> UVA-11210-Chinese Mahjong

UVA-11210-Chinese Mahjong

編輯:C++入門知識

UVA-11210-Chinese Mahjong


訓練指南24頁的題 真是醉了 以為死循環了 原來是循環套的太多了 出一組樣例 500S+ 遞歸盡量減少嵌套循環 會死 我的復雜度34*14*13*12*11*10*9*8*7*6*5*4*3*2*1 提前腦子不好用啊!!!
特別注意以後回溯千萬別忘記調用函數後還要把變量改回來

#include
#include
#include
#include
#include
using namespace std;
vector have;
set ans;
int ji = 0,kase = 0;
bool zuhe(vector now)
{
    int flagzong = 0;
    for(int i = 0; i < now.size(); i++)
        if(now[i] != 99)
        {
            flagzong = 1;
            break;
        }
    if(!flagzong) return true;  //終於完事了
    for(int i = 0; i < now.size(); i++)
        for(int j = 0; j < now.size(); j++)
            for(int k = 0; k < now.size(); k++)
            {
                if(i == j || i == k || j == k || now[i] == 99 || now[j] == 99 || now[k] == 99) continue;
                int a = now[i],b = now[j],c = now[k];
                int flag = 0;
                if(a == b && a == c)    //刻子
                {
                    vector now1(now);
                    now1[i] =99;
                    now1[j] =99;
                    now1[k] =99;
                    if(zuhe(now1)) return true;
                }
                else
                if((a >= 0 && a <= 8 && b >= 0 && b <= 8 && c >= 0 && c <= 8)||(a >= 9 && a <= 17 && b >= 9 && b <= 17 && c >= 9 && c <= 17)||(a >= 18 && a <= 26 && b >= 18 && b <= 26 && c >= 18 && c <= 26)) //順子
                {
                    if(a + 1 == b && b + 1 == c) flag = 1;
                    if(a + 1 == c && c + 1 == b) flag = 1;
                    if(b + 1 == a && a + 1 == c) flag = 1;
                    if(b + 1 == c && c + 1 == a) flag = 1;
                    if(c + 1 == a && a + 1 == b) flag = 1;
                    if(c + 1 == b && b + 1 == a) flag = 1;
                    if(flag)
                    {
                        vector now1(now);
                        now1[i] =99;
                        now1[j] =99;
                        now1[k] =99;
                        if(zuhe(now1)) return true;
                    }
                }
            }
    return false;
}
bool ting(vector now)  //選擇兩個牌做將
{
    for(int i = 0; i < now.size(); i++)
        for(int j = 0; j < now.size(); j++)
        {
            if(i == j || now[i] != now[j]) continue;
            vector temp(now);
            temp[i] = 99;
            temp[j] = 99;
            if(zuhe(temp)) return true;

        }
    return false;
}
void solve()
{
    for(int i = 0; i < 34; i++)
    {
        int countt = 0;
        for(int j = 0; j < have.size(); j++)
            if(have[j] == i) countt++;
        if(countt < 4)
        {
            vector temp(have);
            temp.push_back(i);
            if(ting(temp)) ans.insert(i);
        }
    }

}
void build(string str)
{
    if(str == "DONG") have.push_back(27);
    if(str == "NAN") have.push_back(28);
    if(str == "XI") have.push_back(29);
    if(str == "BEI") have.push_back(30);
    if(str == "ZHONG") have.push_back(31);
    if(str == "FA") have.push_back(32);
    if(str == "BAI") have.push_back(33);
    if(str[1] == 'T') have.push_back(str[0] - '0' - 1);
    if(str[1] == 'S') have.push_back(str[0] - '0' + 8);
    if(str[1] == 'W') have.push_back(str[0] - '0' + 17);
}
void print()
{
    set::iterator it;
    if(ans.empty())
    {
        printf(" Not ready\n");
        return;
    }
    for(it = ans.begin(); it != ans.end(); it++)
    {
        printf(" ");
        if((*it) >= 0 && *it <= 8) printf("%dT",(*it) + 1);
        if((*it) >= 9 && *it <= 17) printf("%dS",(*it) - 8);
        if((*it) >= 18 && *it <=26) printf("%dW",(*it) - 17);
        if((*it) == 27) printf("DONG");
        if((*it) == 28) printf("NAN");
        if((*it) == 29) printf("XI");
        if((*it) == 30) printf("BEI");
        if((*it) == 31) printf("ZHONG");
        if((*it) == 32) printf("FA");
        if((*it) == 33) printf("BAI");
    }
    printf("\n");
    return;
}
int main()
{
    string str;
    while(cin>>str && str != "0")
    {
        build(str);
        ji++;
        if(ji % 13 == 0)
        {
            solve();
            printf("Case %d:",++kase);
            print();
            ji = 0;
            have.clear();
            ans.clear();
        }
    }
    return 0;
}

以下是佳神的代碼:

#include
#include
int mj[20], cnt[35];
const char* mahjong[]={"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 getNum(char *str) { //將牌面轉換為編號
    for (int i = 0; i < 34; i++) {
        if (!strcmp(mahjong[i], str)) return i;
    }
}
int check2(int n) {
    for (int i = 0; i < 34; i++) { //刻子
        if (cnt[i] >= 3) {
            if (n == 3) return 1;
            cnt[i] -= 3;
            if (check2(n + 1)) return 1;
            cnt[i] += 3;
        }
    }
    for (int i = 0; i <= 24; i++) { //順子
        if (i % 9 <= 6 && cnt[i] && cnt[i + 1] && cnt[i + 2]) {
            if (n == 3) return 1;
            cnt[i]--;
            cnt[i + 1]--;
            cnt[i + 2]--;
            if (check2(n + 1)) return 1;
            cnt[i]++;
            cnt[i + 1]++;
            cnt[i + 2]++;
        }
    }
    return 0;
}
int check() {
    for (int i = 0; i < 34; i++) {
        if (cnt[i] >= 2) {//將
            cnt[i] -= 2;
            if (check2(0)) return 1;
            cnt[i] += 2;
        }
    }
    return 0;
}
int main() {
    char str[3];
    int Case = 1;
    while (scanf("%s", str) == 1) {
        if (strcmp(str, "0") == 0) break;
        printf("Case %d:", Case++);
        mj[0] = getNum(str);
        for (int i = 1; i < 13; i++) {
            scanf("%s", str);
            mj[i] = getNum(str);//將牌面轉化為編號
        }
        int flag = 0;
        for (int i = 0; i < 34; i++) {//枚舉34種可能和的情況
            memset(cnt, 0, sizeof(cnt));
            for (int j = 0; j < 13; j++) {
                cnt[mj[j]]++;//統計每張牌出現次數
            }
            if (cnt[i] >= 4) continue;//已出現四次則不再考慮這張牌
            cnt[i]++;
            if (check()) {
                flag = 1;
                printf(" %s", mahjong[i]);
            }
        }
        if (!flag) printf(" Not ready/n");
        else printf("/n");
    }
    return 0;
}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved