bzoj1028

时间:2019-02-17
本文章向大家介绍bzoj1028,主要包括bzoj1028使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

模拟题:
枚举最后一张牌,枚举对子;

判断当前方案是否可行:用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;

}