注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

ydc的博客

 
 
 

日志

 
 

bzoj 1028  

2013-02-05 13:14:47|  分类: bzoj |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

麻将:

我终于知道怎么玩麻将了……

首先枚举等待牌,再枚举对子牌。

然后我们从1~n来扫一遍,如果现在 sum[i]不能被3整除,那么他  必须  跟后两个数搭配几下变成能被3整除的。然后如果能被3整除,那么只要三个连续的一组可行,则三个相同的一组 必定也可行。因为如果有一种方案是3个连续的而最小数又能被3整除,那这种就必须有3n组,3n组的话三个相同的为一组的方案也就存在了。

所以方法就是,n^2枚举等待牌和对子牌,o(n)扫描。扫描方法是,从1~n来做,如果sum[i]不能整除三就消掉几个让他能整除三,然后就三个为一组的消去。上面已经证明如果存在一种可行解这种方案就必然可行

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#define MAXN 1010
using namespace std;
int sum[MAXN],temp[MAXN],n,m,ans[MAXN],tot;
void read()
{
    scanf("%d %d",&n,&m);
    for(int i=1,p;i<=3*m+1;i++)
    {
        scanf("%d",&p);
        sum[p]++;
    }
}
bool check()
{
    for(int i=1;i<=n;i++)
    {
        if(temp[i]<0)  return false;
        if(temp[i]%3)
        {
            if(i>n-2)  return false;
            int x=(temp[i]-1)%3+1;
            temp[i]-=x,temp[i+1]-=x,temp[i+2]-=x;
        }
    }
    return true;
}
void solve()
{
    for(int i=1;i<=n;i++)
    {
        bool mark=false;
        memcpy(temp,sum,sizeof(sum));
        temp[i]++;
        for(int j=1;j<=n&&!mark;j++)
            if(temp[j]>=2)
            {
                temp[j]-=2;
                if(check())  mark=true;
                memcpy(temp,sum,sizeof(sum));
                temp[i]++;
            }
        if(mark)  ans[++tot]=i;
    }
}
void print()
{
    if(tot==0)  printf("NO\n");
    for(int i=1;i<=tot;i++)
        printf("%d%c",ans[i],i<tot?' ':'\n');
}
int main()
{
    read();
    solve();
    print();
    return 0;
}



  评论这张
 
阅读(240)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017