模拟题:
枚举最后一张牌,枚举对子;
判断当前方案是否可行:用dp的思想考虑处理数字i的牌时,前i-1张牌已经全部打完,对于数字为i的牌,假设有现在还有num张,那么num%3张一定是通过和后面的两张打顺子打出去的,若后面两张的牌数<num%3,该方案不可行。处理完后,若数字为n和n-1的牌的数不为3的倍数,说明后两种牌打不出去,该方案也不可行
复杂度:O(n^3) 因为没有跑满,我的常数写大了也过了
/**************************************************************
Problem: 1028
User: syh0313
Language: C++
Result: Accepted
Time:460 ms
Memory:1304 kb
****************************************************************/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
using
namespace
std;
int
n,m,a[3050],num[410],topt,now[410];
bool
f=0;
bool
ok()
{
memset
(num,0,
sizeof
num);
for
(
int
i=1;i<=topt;i++) num[a[i]]++;
for
(
int
dui=1;dui<=n;dui++)
if
(num[dui]>=2)
{
bool
ff=1;
for
(
int
i=1;i<=n;i++)
if
(i!=dui) now[i]=num[i];
else
now[i]=num[i]-2;
for
(
int
i=1;i<=n-2;i++)
if
(now[i])
{
int
dec=now[i]%3;
if
(now[i+1]<dec || now[i+2]<dec) {ff=0;
break
;}
now[i+1]-=dec; now[i+2]-=dec;
}
if
(now[n-1]%3!=0 || now[n]%3!=0) ff=0;
if
(ff)
return
1;
}
return
0;
}
int
main()
{
scanf
(
"%d%d"
,&n,&m); topt=3*m+2;
for
(
int
i=1;i<=3*m+1;i++)
scanf
(
"%d"
,&a[i]);
for
(
int
i=1;i<=n;i++)
{
a[topt]=i;
if
(ok())
printf
(
"%d "
,i),f=1;
}
if
(!f)
puts
(
"NO"
);
return
0;
}