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;

}

 

  

 

你可能感兴趣的:(2007)