思路:暴力剪枝,先在n个中选出k个,然后先不考虑顺序,看所有抑或值能否包括l到ans,不能则退出再选,能则考虑顺序情况。
反思:昨天到今天都曲解题意了。。。wa了几发看别人博客才发现,还有我剪枝太不优越了,T了几发果断重写。
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> using namespace std; int a[22]; int b[10]; int n,k,l; int ans; bool v[20]; int c[10][10]; bool vis[111]; void check(int num,int sum) { vis[sum]=1; if(num==k)return; check(num+1,sum); check(num+1,sum^b[num]); } void go() { memset(vis,0,sizeof(vis)); check(0,0); if(!vis[l])return; for(int i=l;i<=ans;i++)if(!vis[i])return; do { memset(vis,0,sizeof(vis)); for(int i=0;i<k;i++) { int s=0; for(int j=0;j<k;j++) { s^=b[(i+j)%k]; vis[s]=1; } } if(!vis[l])continue; int x; for(x=l;;x++)if(!vis[x])break; ans=max(ans,x-1); }while(next_permutation(b,b+k)); } void dfs(int u,int num) { if(num==k) { go(); return; } for(int i=u;i<n;i++) { b[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); ans=0; memset(v,0,sizeof(v)); dfs(0,0); printf("%d\n",ans); } return 0; }