您的位置:首页 > 大数据 > 人工智能

【暴力+优化】【2014 Multi-University Training Contest 2】ZCC loves cards

2014-08-08 11:15 495 查看
ZCC loves cards

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

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 

题目大意:从N张牌里选K张牌,随意顺序摆成一个圈,在这个圈上随意取连续的M张,求他们的Xor值,使得Xor的结果覆盖L..R这个区间,(Xor的结果可以超出这个区间,但是这个区间必须被完全覆盖掉),求一个最大的R

思路:看到题目N<=20,K<=6,觉得数据范围挺小的,暴力生成全排列可以有,但是仔细考虑之后发现暴力在时间上依旧是不可接受的,然后就换了个思路,对暴力进行优化。

首先,我们先让输入数据有序,使得我们之后生成全排列方便一些,然后暴力枚举K 个数出来,判断这K个数的异或结果是否能满足当前的R,不能满足显然就不用去生成全排列了,如果满足,则将这K个数生成一个全排列,更新R的值即可。

整个程序跑完只要500Ms。

但是这道题做的过程简直艰辛……从开始到过题用了3个小时,调试的时候调试得蛋都要碎掉了。在思路清晰的情况下居然整个程序有3个Bug,简直不能忍,代码能力有待提高啊……

调试语句略多……代码将就着看下吧……

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>

using namespace std;

int n,k,l,r;
int tmp[10],boo[200],a[50];

void work(){
int c[10]={0};
for (int i=0;i<k;i++){
c[i]=tmp[i];
//cout<<c[i]<<" ";
}
//cout<<endl;

do{
/*
for (int i=0;i<k;i++){
cout<<c[i]<<" ";
}
cout<<endl;
*/
memset(boo,0,sizeof(boo));
int now=0;
for (int i=0;i<k;i++){
now=0;
for (int j=i;j<k+i;j++){
now=now^c[j%k];
boo[now]=1;
}
}

//cout<<"1111"<<endl;

for (int i=l;i<=200;i++){
if (boo[i]==0){
r=max(r,i-1);
break;
}
}

//cout<<"2222"<<endl;

}while(next_permutation(c+1,c+k));
//}while (0);

//cout<<endl;
}

void dfs2(int now,int step){
boo[now]=1;
if (step>=k) return;

dfs2(now^tmp[step],step+1);
dfs2(now,step+1);
}

bool check(){

for (int i=l;i<=r;i++){
if (boo[i]==0){
return false;
}
}

return true;
}

void dfs(int pre,int step){
if (step>=k){
memset(boo,0,sizeof(boo));
dfs2(0,0);
/*
for (int i=0;i<k;i++){
cout<<tmp[i]<<" ";
}
cout<<endl;
*/
if (check()) {
//cout<<"success!"<<endl;
work();
}

return;
}

for (int i=pre;i<n;i++){
tmp[step]=a[i];
dfs(i+1,step+1);
}
}

int main(){
while (scanf("%d%d%d",&n,&k,&l)!=EOF){
r=l-1;
for (int i=0;i<n;i++){
scanf("%d",a+i);
}

sort(a,a+n);
//for (int i=0;i<n;i++) cout<<a[i]<<" ";
//cout<<endl;
dfs(0,0);

if (r==l-1){
printf("%d\n",0);
}
else {
printf("%d\n",r);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  多校
相关文章推荐