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

hdu4431 Mahjong 枚舉搜索。。

編輯:C++入門知識

japanese麻將什麼玩意。。都沒有豪華七對。。。

沒什麼難的 就是枚舉搜索了

分三種類型的胡牌

f1是七對 f2是十三幺 f3是普通的胡牌 就先找一對 再找三個三個的

就是一直超時。。在峰峰的指導下加了好多剪枝 注釋都標出來了。。這樣才過 而且好慢。。

#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <map>
using namespace std;

int cnt[40],res,ans[40];
map<string,int>mp;
void init()
{
    mp["1m"]=1; mp["1s"]=11; mp["1p"]=21;
    mp["2m"]=2; mp["2s"]=12; mp["2p"]=22;
    mp["3m"]=3; mp["3s"]=13; mp["3p"]=23;
    mp["4m"]=4; mp["4s"]=14; mp["4p"]=24;
    mp["5m"]=5; mp["5s"]=15; mp["5p"]=25;
    mp["6m"]=6; mp["6s"]=16; mp["6p"]=26;
    mp["7m"]=7; mp["7s"]=17; mp["7p"]=27;
    mp["8m"]=8; mp["8s"]=18; mp["8p"]=28;
    mp["9m"]=9; mp["9s"]=19; mp["9p"]=29;
    mp["1c"]=31;mp["2c"]=32; mp["3c"]=33;
    mp["4c"]=34;mp["5c"]=35; mp["6c"]=36;
    mp["7c"]=37;
}

int f1()//7dui
{
    int a=0;
    for(int i=1;i<=38;i++)
    {
        if(cnt[i]==2) a++;
    }
    return a==7;
}

int f2()//13yao
{
    int i,j;
    for(i=0;i<30;i+=10)
    {
        if(!cnt[i+1]||!cnt[i+9]) return 0;
        for(j=2;j<9;j++)
            if(cnt[i+j]) return 0;
    }
    for(i=31;i<=37;i++)
        if(!cnt[i]) return 0;
    return 1;
}

int dfs()
{
    int i;
    if(res==0) return 1;
    for(i=1;i<30;i++)
    {
        if(cnt[i]>=3)
        {
            cnt[i]-=3;
            res-=3;
            if(dfs()){
                cnt[i]+=3;
                res+=3;
                return 1;
            }
            cnt[i]+=3;
            res+=3;
        }
    }
    for(i=1;i<30;i++)
    {
        if(cnt[i]&&cnt[i+1]&&cnt[i+2])
        {
            cnt[i]--;
            cnt[i+1]--;
            cnt[i+2]--;
            res-=3;
            if(dfs()){
                cnt[i]++;
                cnt[i+1]++;
                cnt[i+2]++;
                res+=3;
                return 1;
            }
            cnt[i]++;
            cnt[i+1]++;
            cnt[i+2]++;
            res+=3;
        }
    }
    return 0;
}

int f3()
{
    int i;
    for(i=1;i<38;i++)
        if(cnt[i]>=2)
        {
            cnt[i]-=2;
            res=12;
            int ok=1;//這裡再加一個剪枝 先找出連不成一句話的三個一樣的
            for(int j=31;j<=37;j++)
            {
                if(cnt[j]==3) res-=3;//減小dfs
                else if(cnt[j]) {ok=0;break;}
            }
            if(!ok) {cnt[i]+=2;continue;}
            if(dfs())
            {
                cnt[i]+=2;
                return 1;
            }
            cnt[i]+=2;
        }
    return 0;
}

int main()
{
    int t,i,k;
    char s[5];
    init();
    scanf("%d",&t);
    while(t--)
    {
        memset(cnt,0,sizeof cnt);
        for(i=0;i<13;i++)
        {
            scanf("%s",s);
            cnt[mp[s]]++;
        }
        for(i=1,k=0;i<=37;i++)
        {
            if(i%10==0||cnt[i]==4) continue;//如果這張牌已經有四個就不用加啦
            cnt[i]++;
            if(cnt[i]==4&&!cnt[i-1]&&!cnt[i+1]){
                cnt[i]--;//如果這張牌有四個 且相鄰兩個都沒有 那一定不能胡
                continue;
            }
            if(f2()){
                ans[k++]=i;
                cnt[i]--;
                continue;
            }
            else if(cnt[i]==1&&!cnt[i-1]&&!cnt[i+1]){
                cnt[i]--;//判斷為不是十三幺後
                continue;//如果這張牌只有一個 而且前後都沒有 那一定不能胡
            }
            if(f1()||f3())
                ans[k++]=i;
            cnt[i]--;
        }
        if(k)
        {
           // sort(ans.begin(),ans.end());//mark
            printf("%d",k);
            for(i=0;i<k;i++)
            {
                if(ans[i]<10)
                    printf(" %dm",ans[i]%10);
                else if(ans[i]<20)
                    printf(" %ds",ans[i]%10);
                else if(ans[i]<30)
                    printf(" %dp",ans[i]%10);
                else printf(" %dc",ans[i]%10);
            }
            putchar('\n');
        }
        else printf("Nooten\n");
    }
    return 0;
}

 

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