http://acm.hdu.edu.cn/showproblem.php?pid=4431
幸亏哥有点麻将基础 提到三种和牌方式
1: 7个不同的对子
2: 传说中的十三幺 m1,m9,s1,s9,p1,p9,c1,c2,c3,c4,c5,c6,c7 然后再多一张 可以是 前面那13张中的任意一张
3: 一个对子 外加 四个 (吃或碰)吃就是三张牌组成的顺子 碰就是三个牌一样
思路 :
枚举添加任意一张牌 但不能使某种牌的个数超过4
然后判定是否是和牌
判定第三种和牌时 先枚举去掉一个对子 然后看是否剩余的牌组成 四个 (吃或碰)
注意:
c1,c2,c3 像 东南西方这类的牌 没有顺子
自己写的时候是因为一个地方数组没有初始化 wa 了很久
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<set>
#include<queue>
#include<stack>
#include<map>
#include<string>
#include<iomanip>
using namespace std;
#define LL long long
const int INF=0x5fffffff;
const double FINF=1e9;
const int N=20;
int s[N];
int c[N];
int m[N];
int p[N];
vector<int>ans;
vector<char>ansc;
bool Two()
{
for(int i=1;i<=9;++i)
{
if(c[i]!=0&&c[i]!=2)
return false;
if(m[i]!=0&&m[i]!=2)
return false;
if(p[i]!=0&&p[i]!=2)
return false;
if(s[i]!=0&&s[i]!=2)
return false;
}
return true;
}
bool Spe()
{
int t2=0;
for(int i=1;i<=7;++i)
{
if(c[i]==2)
++t2;
else if(c[i]!=1)
return false;
}
if(m[1]==2)
++t2;
else if(m[1]!=1)
return false;
if(m[9]==2)
++t2;
else if(m[9]!=1)
return false;
if(s[1]==2)
++t2;
else if(s[1]!=1)
return false;
if(s[9]==2)
++t2;
else if(s[9]!=1)
return false;
if(p[1]==2)
++t2;
else if(p[1]!=1)
return false;
if(p[9]==2)
++t2;
else if(p[9]!=1)
return false;
if(t2!=1)
return false;
return true;
}
bool Func(int tmp[],int l)
{
if(tmp[l]==1||tmp[l]==2||tmp[l]==4)
{
--tmp[l];
if(tmp[l+1]==0) return false;
else --tmp[l+1];
if(tmp[l+2]==0) return false;
else --tmp[l+2];
}
if(tmp[l]==3)
tmp[l]=0;
return true;
}
bool Meld()
{
int s1[N],m1[N],p1[N];
for(int i=1;i<N;++i)
{
if(c[i]!=0&&c[i]!=3)
return false;
s1[i]=s[i];
p1[i]=p[i];
m1[i]=m[i];
}
int l=1;
while(l<=9)
{
if(!s1[l]&&!m1[l]&&!p1[l])
{++l;continue;}
if(!Func(s1,l))
return false;
if(!Func(m1,l))
return false;
if(!Func(p1,l))
return false;
}
return true;
}
bool Normal()
{
for(int i=1;i<=9;++i)
{
if(c[i]>=2)
{
c[i]-=2;
if(Meld())
{c[i]+=2;return true;}
c[i]+=2;
}
if(p[i]>=2)
{
p[i]-=2;
if(Meld())
{p[i]+=2;return true;}
p[i]+=2;
}
if(m[i]>=2)
{
m[i]-=2;
if(Meld())
{m[i]+=2;return true;}
m[i]+=2;
}
if(s[i]>=2)
{
s[i]-=2;
if(Meld())
{s[i]+=2;return true;}
s[i]+=2;
}
}
return false;
}
bool Win()
{
if(Two())
return true;
if(Spe())
return true;
if(Normal())
return true;
return false;
}
void Fans(int stmp[],char k)
{
int w=9;
if(k=='c')
w=7;
for(int i=1;i<=w;++i)
{
if(stmp[i]<4)
{
++stmp[i];
if(Win())
{ans.push_back(i);ansc.push_back(k);}
--stmp[i];
}
}
}
int main()
{
//freopen("data.txt","r",stdin);
int T;
char stmp[5];
scanf("%d",&T);
while(T--)
{
for(int i=0;i<N;++i)
s[i]=c[i]=m[i]=p[i]=0;
for(int i=1;i<=13;++i)
{
scanf("%s",stmp);
int k=stmp[0]-'0';
if(stmp[1]=='c')
++c[k];
else if(stmp[1]=='p')
++p[k];
else if(stmp[1]=='m')
++m[k];
else if(stmp[1]=='s')
++s[k];
}
ans.clear();
ansc.clear();
Fans(m,'m');
Fans(s,'s');
Fans(p,'p');
Fans(c,'c');
if(ans.size()==0)
printf("Nooten\n");
else
{
printf("%d",ans.size());
for(unsigned int i=0;i<ans.size();++i)
{
printf(" %d%c",ans[i],ansc[i]);
}
printf("\n");
}
}
return 0;
}
转载于:https://www.cnblogs.com/liulangye/archive/2012/11/03/2752805.html