清一色胡牌問題


題目描述:
清一色是麻將番種之一,指由一種花色的序數牌組成的和牌.
數字1-9,每個數字最多有4張牌
我們不考慮具體花色,我們只看數字組合。
刻子:三張一樣的牌;如: 111, 222, 333, …, 999
順子:三張連續的牌;如: 123, 234, 345, …, 789
對子:兩張相同的牌;如: 11, 22, 33, …, 99
需要實現一個程序,判斷給定牌,是否可以和牌(胡牌)。
和牌要求:

    麻將牌張數只能是 2, 5, 8, 11, 14
    給定牌可以組合成,除1個對子以外其他都是刻子或順子
    舉例: - “11” -> “11”, 1對子,可以和牌
    “11122233” -> “111”+“222”+“33”, 2刻子,1對子,可以
    “11223344567” -> “11”+“234”+“234”+“567”, 1對子,3順子,可以
    -> “123”+“123”+“44”+“567”, 另一種組合,也可以
    輸入描述:
    合法C字符串,只包含’1’-‘9’,且已經按從小到大順序排好;字符串長度不超過15。同一個數字最多出現4次,與實際相符。
    輸出描述:
    C字符串,“yes"或者"no”
    示例1
    輸入
    2244
    輸出no

算法:深搜(dfs),我們只需要在每次判斷時去掉順子或者刻子,不斷搜索下去。我們關注的是搜索的出口,也就是麻將的長度(小於2不能和牌,等於2需判斷是否為對子)即可

#include<string>
#include<algorithm>
#include<iostream>
using namespace std;
bool dfs(const string& s){
    if(s.size()<2)return false;
    if(s.size()==2)return s[0]==s[1];
    bool flag=false;
    auto beg=s.begin(),ed=s.end();
    while(ed-beg>2){
        if(*beg==*(beg+1)&&*beg==*(beg+2)){
            string tmp1(s.begin(),beg);
            string tmp2(beg+3,ed);
            flag|=dfs(tmp1+tmp2);
        }
        else if(*beg+1==*(beg+1)){
            int cnt=0;
            char tmp=*(beg+1);
            auto it=beg+1;
            while(*it==tmp){
                cnt++;
                if(++it==ed){
                    cnt=-1;
                    break;
                }
            }
            if(cnt>0&&tmp+1==*it){
                string tmp1(s.begin(),beg);
                string tmp2;
                tmp2.insert(0,cnt-1,tmp);
                string tmp3(it+1,ed);
                flag|=dfs(tmp1+tmp2+tmp3);
            }
        }
        ++beg;
    }
    return flag;
}
int main(void){
    string s;
    cin>>s;
    sort(s.begin(),s.end());
    cout<<(dfs(s)?"yes":"no")<<endl;
    return 0;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM