[bzoj1028][JSOI2007]麻将【暴力】【贪心】
【题目链接】
http://www.lydsy.com/JudgeOnline/problem.php?id=1028
【题解】
枚举听哪张牌,再枚举将牌是哪一对。
在从前往后贪心判断是否正确,方法是:
能取刻子尽量选刻子,剩下的与后面组成顺子。
时间复杂度:O()
/* --------------
user Vanisher
problem bzoj-1028
----------------*/
# include <bits/stdc++.h>
# define ll long long
# define N 510
using namespace std;
int read(){
int tmp=0, fh=1; char ch=getchar();
while (ch<'0'||ch>'9'){if (ch=='-') fh=-1; ch=getchar();}
while (ch>='0'&&ch<='9'){tmp=tmp*10+ch-'0'; ch=getchar();}
return tmp*fh;
}
int cnt[N],now[N],ans[N],ansnum,n,m;
int main(){
n=read(), m=read();
for (int i=1; i<=3*m+1; i++)
cnt[read()]++;
for (int i=1; i<=n; i++){
cnt[i]++;
bool f=false;
for (int j=1; j<=n; j++)
if (cnt[j]>1){
for (int k=1; k<=n; k++)
now[k]=cnt[k];
now[j]-=2;
bool flag=true;
for (int k=1; k<=n-2; k++){
if (now[k]<0){
flag=false;
break;
}
now[k]%=3;
while (now[k]){
now[k]--;
now[k+1]--;
now[k+2]--;
}
}
now[n-1]%=3; now[n]%=3;
if (now[n-1]==0&&now[n]==0&&flag==true){
f=true;
break;
}
}
if (f==true)
ans[++ansnum]=i;
cnt[i]--;
}
if (ansnum==0)
printf("NO\n");
else {
printf("%d",ans[1]);
for (int i=2; i<=ansnum; i++)
printf(" %d",ans[i]);
printf("\n");
}
return 0;
}