思路
题目比较长,不过题意很清晰:给一副麻将,判断有没有胡。如果没有,那么输出有多少种出牌的方法,使得出牌后可以听。对于每种方法,按顺序输出它胡哪张牌。
总共就 34 34 34 张牌,一般来说不存在超时的问题。
给出一副牌,直接深搜可以判断有没有胡。这个复杂度并不高,搜索深度最大在 4 4 4 左右。
没胡的话,还需判断它出哪张牌后可以听,听哪些牌。
可以双重循环,枚举这次出的牌,下次得到的牌,再通过上面的深搜判断经过这些操作后能不能胡,记录答案。
不要开mp[26],也不要开mp[30],不然会莫名其妙调一晚上代码。
#include<bits/stdc++.h>
using namespace std;
const string rmp[35]={" ",
"1w", "2w", "3w", "4w", "5w", "6w", "7w", "8w", "9w",
"1b", "2b", "3b", "4b", "5b", "6b", "7b", "8b", "9b",
"1s", "2s", "3s", "4s", "5s", "6s", "7s", "8s", "9s",
"1z", "2z", "3z", "4z", "5z", "6z", "7z"
};
char s[30]; int T,a[40],mp[150],op[40][40],tot[40];
bool dfs(int x,int pr){
bool flag=false;
while(a[x]==0&&x<=34) x++;
if(x>34) return pr==1;
if(a[x]>=3){
a[x]-=3;
flag=dfs(x,pr);
a[x]+=3;
if(flag) return true;
}
if(a[x]>=2&&pr==0){
a[x]-=2;
flag=dfs(x,pr+1);
a[x]+=2;
if(flag) return true;
}
if(a[x]&&a[x+1]&&a[x+2]&&(x-1)/9==(x+2-1)/9&&x+2<=27){
a[x]--,a[x+1]--,a[x+2]--;
flag=dfs(x,pr);
a[x]++,a[x+1]++,a[x+2]++;
if(flag) return true;
}
return false;
}
void solve(){
int ans=0;
cin>>(s+1);
memset(a,0,sizeof(a));
memset(tot,0,sizeof(tot));
for(int i=1;i<=27;i++)
a[s[i]-'0'+mp[s[i+1]]]++;
if(dfs(1,0)) return (void)(cout<<"Tsumo!\n");
for(int i=1;i<=34;i++){
if(a[i]==0) continue;
for(int j=1;j<=34;j++){
a[i]--,a[j]++;
if(dfs(1,0)) op[i][++tot[i]]=j;
a[i]++,a[j]--;
}
if(tot[i]) ans++;
}
cout<<ans<<"\n";
for(int i=1;i<=34;i++) if(tot[i]){
cout<<rmp[i]<<" ";
for(int j=1;j<=tot[i];j++) cout<<rmp[op[i][j]];
cout<<"\n";
}
}
int main(){
mp['w']=0,mp['b']=9,mp['s']=18,mp['z']=27;
ios::sync_with_stdio(false);
for(cin>>T;T;T--) solve();
}