麻将
麻将([JSOI2007])
原题链接:luogu P4050
解题思路:
这可是民间国粹啊!虽然我不会打
这题如果会打麻将的同学就可以很快的理解题意,像我这种不会的,得搞很久才明白。
由于胡要必定有一个对子,所以,我们可以枚举每一种可能性,使其凑成对子以上个数。然后继续进行各种刻子和顺子的判断。
AC代码如下:
#include<bits/stdc++.h>
using namespace std;
int n,m,t[4001],a[4001];
bool bj;
bool check()
{
for(int i=1;i<=n;i++)
{
if(t[i]>=2)//只有凑成对子以上个数时才能胡牌。
{
bool ok=1;//进行标记是否找到。
t[i]-=2;//将其当做对子。
for(int j=1;j<=n+2;j++)a[j]=t[j];//不能改变原来数组的值。
for(int j=1;j<=n+2;j++)
{
if(a[j]<0)//如果小于0则代表不能胡牌,直接退出循环,进行下一个对子的判断。
{
ok=0;
break;
}
a[j]%=3;//刻子
a[j+1]-=a[j];//顺子
a[j+2]-=a[j];//顺子
}
t[i]+=2;
if(ok)return 1;
}
}
return 0;
}
int main()
{
cin>>n>>m;
for(int i=1,x;i<=m*3+1;i++)cin>>x,t[x]++;//用桶来存储麻将个数。
for(int i=1;i<=n;i++)
{
t[i]++;
if(check())bj=1,cout<<i<<" "; //只要找到一个解就标记找到了,并输出解。
t[i]--;
}
if(!bj)cout<<"NO";
return 0;
}