HDU4876 ZCC loves cards

来源:互联网 发布:获取手机的gps数据 编辑:程序博客网 时间:2024/05/02 02:10

ZCC loves cards


Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 787 Accepted Submission(s): 170


Problem Description
ZCC loves playing cards. He has n magical cards and each has a number on it. He wants to choose k cards and place them around in any order to form a circle. He can choose any several consecutive cards the number of which is m(1<=m<=k) to play a magic. The magic is simple that ZCC can get a number x=a1⊕a2...⊕am, which ai means the number on the ith card he chooses. He can play the magic infinite times, but once he begin to play the magic, he can’t change anything in the card circle including the order.
ZCC has a lucky number L. ZCC want to obtain the number L~R by using one card circle. And if he can get other numbers which aren’t in the range [L,R], it doesn’t matter. Help him to find the maximal R.


Input
The input contains several test cases.The first line in each case contains three integers n, k and L(k≤n≤20,1≤k≤6,1≤L≤100). The next line contains n numbers means the numbers on the n cards. The ith number a[i] satisfies 1≤a[i]≤100.
You can assume that all the test case generated randomly.


Output
For each test case, output the maximal number R. And if L can’t be obtained, output 0.


Sample Input
4 3 1
2 3 4 5


Sample Output
7

Hint
⊕ means xor



Author
镇海中学


题意:选k个数,排成一个环,从这个环上取连续的几个数,得到他的异或值,求出最大的r,使l-r这些数都能异或出来,如果l<r输出0.

比赛看到这题毫无思路,最后也只出了最后那到水题,后面看题解,直接暴力,可是暴力都暴力不出啊,现在搜了几份代码也终于弄出来怎么暴力了(详见代码),这里的也有个关键地方要剪枝,不然就TLE了,就是随机取了k个数之后,看能不能满足l-r,如果随机取的且没有按顺序都没满足,如果这个就不要排序再异或取值了。

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;int save[25],a[25],have[25],v[210],vis[210],n,k,l,r;void calmax(int cur,int sum)    //这个函数的作用是将选择的k的数的异或值全部计算并记录下来{    vis[sum]=1;    if(cur==k)        return;    calmax(cur+1,sum^save[cur]);    calmax(cur+1,sum);}bool maxcal()   //判断选的k个数异或出来的值是否填满了l-r之间{    memset(vis,0,sizeof(vis));    calmax(0,0);    for(int i=l;i<=r;i++)        if(!vis[i])        return 0;    return 1;}void cal(){    if(!maxcal())   //剪枝随机取k个(不考虑连续),如果这样不满足,连续一定不满足        return;    for(int i=0;i<k;i++)        have[i]=save[i];    do{     //下面就是枚举这k个数的各种顺序        memset(v,0,sizeof(v));        for(int i=0;i<k;i++)        {            int ans=0;            for(int j=i;j<k+i;j++)            {                ans^=have[(j%k)];                v[ans]=1;            }        }        for(int i=l;i<=l+k*k;i++)        {            if(!v[i])            {                r=max(r,i-1);                break;            }        }    }while(next_permutation(have+1,have+k));}void dfs(int cur,int num){    if(num==k)    {        cal();        return;    }    for(int i=cur;i<n;i++)  //选k个数    {        save[num]=a[i];        dfs(i+1,num+1);    }}int main(){    while(scanf("%d%d%d",&n,&k,&l)!=EOF)    {        for(int i=0;i<n;i++)            scanf("%d",&a[i]);        sort(a,a+n);        r=l-1;        dfs(0,0);        if(r<l)            printf("0\n");        else            printf("%d\n",r);    }    return 0;}


0 0
原创粉丝点击