[bzoj1028][JSOI2007]麻将【暴力】【贪心】

【题目链接】
  http://www.lydsy.com/JudgeOnline/problem.php?id=1028
【题解】
  枚举听哪张牌,再枚举将牌是哪一对。
  在从前往后贪心判断是否正确,方法是:
    能取刻子尽量选刻子,剩下的与后面组成顺子。
 时间复杂度:O(n3)

/* --------------
    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;
}
posted @ 2018-03-02 08:30  Vanisher  阅读(98)  评论(0编辑  收藏  举报