BZOJ 1028: [JSOI2007]麻将
/*
* 题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1028
* 顺子:三个相连的数字
* 刻子:三个相同的数字
* 对子:两个相同的数字
* 和牌:m个顺子或者刻子加上一个对子
* 现在给出3*m+1个牌,问能不能够和牌,能够和牌的牌号分别可以是。。。
*
* 分析:
* 直接贪心加枚举对子,然后再判能不能够和牌
*
* */
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int X = 3005;
int a[X],n,m;
int b[X];
bool check(){
for(int k=1;k<=n;k++){
if(a[k]<2)
continue;
bool ok = true;
for(int i=1;i<=n;i++)
b[i] = a[i];
b[k] -= 2;
for(int i=1;i<=n;i++){
if(b[i]==0)
continue;
b[i] %= 3;
if(b[i]==0)
continue;
if(i>n-2){
ok = false;
break;
}
if(b[i+1]<b[i]||b[i+2]<b[i]){
ok = false;
break;
}
b[i+1] -= b[i];
b[i+2] -= b[i];
b[i] = 0;
}
if(ok)
return true;
}
return false;
}
int main(){
freopen("sum.in","r",stdin);
while(cin>>n>>m){
int tot = 3*m+1;
int x;
memset(a,0,sizeof(a));
for(int i=1;i<=tot;i++){
scanf("%d",&x);
a[x] ++;
}
bool ok = false;
for(int i=1;i<=n;i++){
a[i] ++;
if(check()){
ok?printf(" "):ok = 1;
printf("%d",i);
}
a[i] --;
}
ok?puts(""):puts("NO");
}
return 0;
}

浙公网安备 33010602011771号