码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 4876 ZCC loves cards【暴力+深搜+剪枝】

时间:2015-05-07 22:13:48      阅读:149      评论:0      收藏:0      [点我收藏+]

标签:

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4876

题意:给你N,l,k三个数,N代表N个数,从中任选k个数,然后

这k个数组成一个环,可以从这个环中选连续的1-k个数进行异或和

,把所得到的值填充到l的后面,使得有一个数r让l-r之间所有的整

整数都被这些异或和填满,求最大的r,也许表达的不太清楚,其实

就是找一个最大的r,使得给定的l到这个r之间所有的数都能够被这些

异或和表示出来,注意异或和要求是连续的数异或的和。

分析:这道题我看了好久没思路,看了大牛的博客好久没理解,脑子

比较笨知识不牢固,是这样的,这道题考察点应该是时间问题,这里

就有一个优化就是,首先就是按平常先C(n,k)进行组合,然后在

进行这k个数要进行排序牌,排序可以用next_permutation()这个

函数,我每得到一个序列就会求的一个r,最终取最大的r,优化点是

假设当前有已一个r,当取第二个组合的时候先按先按这k个数不必连续

的数进行异或和,是否可以达到当前l-r之间所有数都表示出来的效果

如果这都不是不出来我就不必再计算这组k个数的组合了,因为k<=6

所以求不必连续的异或和不会用太多时间,这里优化了时间问题就解决了

然后献上代码:

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
using namespace std;
const int maxk=100+10;
const int maxn=200+10;
int tmp[maxk],num[maxn],test[maxn],l,r,n,k;
bool visit[maxn];
void set(int sum,int now)
{
    if(now==k+1)return;
    visit[sum]=true;
    set(sum^tmp[now],now+1);
    set(sum,now+1);
}
bool judge()
{
    memset(visit,false,sizeof(visit));
    set(0,0);
    for(int i=l;i<=r;i++)
    if(!visit[i])
    return false;
    return true;
}
void control()
{
    if(!judge())
    return;
    for(int i=0;i<k;i++)
    {
        test[i]=tmp[i];
    }
    do{ 
        memset(visit,false,sizeof(visit)); 
        for(int i=0;i<k;i++)
        { 
            int sum=0;
            for(int j=i;j<i+k;j++)
            {
                sum^=test[j%k];
                visit[sum]=true;
            }
            for(int j=l;j<110;j++)
            if(!visit[j])
            {
                r=max(r,j-1);
                break;
            }
        }
    }while(next_permutation(test,test+k));
}
void dfs(int con,int now)
{
    if(now==k)
    control();
    for(int i=con;i<n;i++)
    {
        tmp[now]=num[i];
        dfs(i+1,now+1);
    }
}
int main()
{
    while(~scanf("%d%d%d",&n,&k,&l))
    {
        for(int i=0;i<n;i++)
        scanf("%d",&num[i]);
        sort(num,num+n);
        r=l-1;
        dfs(0,0);
        if(r<l)
        printf("0\n");
        else
        printf("%d\n",r);
    }
    return 0;
}
                    

HDU 4876 ZCC loves cards【暴力+深搜+剪枝】

标签:

原文地址:http://blog.csdn.net/letterwuyu/article/details/45565511

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!