我决定记录下这么恶心的代码。比赛的时候头晕脑胀,写得好搓,错的地方好多好多,回来调了好久。。。。
做法大概就是C(20,6)选出卡牌后,再k!枚举排列,再k*k得出该排列能得出什么数字。
当然,光这样做绝对会T,里面加了各种剪枝后就1650ms险过了。。
最主要的剪枝是选出k张牌后,看牌能不能组成L~ans里面各个数字,能才进行下一步。然后k!可以拆成(k-x)!*(x!)。。不过这里其实大概没什么大优化吧
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #include<cmath> #include<queue> #include<ctime> #include<map> #include<set> #include<stack> #include<list> #define maxn 200010 #define LL long long #define BUG printf("hehe!~ ") #define mod 1000000007 using namespace std ; int a[22],b[22]; bool dp1[222],dp2[222],dp[222]; bool had[132]; int cm[10],cmlen; int R; int main() { //freopen("1005.in","r",stdin); //freopen("my.out","w",stdout); int n,k,L; int tk,t,cnt,tmp,bcnt,ttmp; int ans; bool flag,flag2; while(scanf("%d%d%d",&n,&k,&L)==3) { for(int i=1;i<=n;++i) scanf("%d",a+i); //sort(a+1,a+1+n,cmp); tk=1<<n; R=0; ans=L; flag = false; for(int i=1;i<tk;++i) { cnt=0; tmp=i; //if(R>=100) break; while(tmp) { if(tmp&1) ++cnt; tmp>>=1; } if(cnt!=k) continue; flag2=true; tmp=i; cnt=1; bcnt=1; while(tmp) { if(tmp&1) b[bcnt++]=a[cnt]; ++cnt; tmp>>=1; } t=1<<k; vector<int> el; memset(had,0,sizeof had); for(int j=1;j<t;++j) { tmp=j; ttmp=0; cnt=1; while(tmp) { if(tmp&1) ttmp^=b[cnt]; tmp>>=1; ++cnt; } if(ans==ttmp) { el.push_back(j); } had[ttmp]=true; //if(L==ttmp) flag2=true; } for(int ii=L;ii<=ans;++ii) if(!had[ii]) { flag2=false; break; } if(el.size()==0) { continue; } else if(flag2) { //BUG; for(int j=0;j<el.size();++j) { tmp = el[j]; vector<int> c; vector<int> d; bool pre; //memset(had,false,sizeof had); //cout<<"b: "; for(int p=1;p<=k;++p) { //cout<<b[p]<<" "; if((1<<(p-1))&tmp) { //c[0]^=b[p]; c.push_back(b[p]); } else { d.push_back(b[p]); } } //cout<<endl; sort(c.begin(),c.end()); sort(d.begin(),d.end()); //cout<<"c: "; //for(int ii=0;ii<c.size();++ii) //cout<<c[ii]<<" "; //cout<<endl; //cout<<"d: "; //for(int ii=0;ii<d.size();++ii) //cout<<d[ii]<<" "; //cout<<endl<<endl; cmlen=0; memset(had,false,sizeof had); for(int ii=0;ii<c.size();++ii) cm[cmlen++]=c[ii]; for(int ii=0;ii<d.size();++ii) cm[cmlen++]=d[ii]; for(int ii=1;ii<=k;++ii) { for(int jj=0;jj<k;++jj) { ttmp=0; for(int kk=0;kk<ii;++kk) { ttmp^=cm[(jj+kk)%k]; } had[ttmp]=true; } } R=0; for(int ii=L;ii<=128;++ii) if(had[ii]) { R=max(R,ii); flag=true; //BUG; } else break; ans=max(R,ans); //BUG; while(next_permutation(d.begin(),d.end())) { //BUG; memset(had,false,sizeof had); cmlen=c.size(); for(int ii=0;ii<d.size();++ii) cm[cmlen++]=d[ii]; //for(int ii=0;ii<cmlen;++ii) //cout<<cm[ii]<<" "; //cout<<endl; for(int ii=1;ii<=k;++ii) { for(int jj=0;jj<k;++jj) { ttmp=0; for(int kk=0;kk<ii;++kk) { ttmp^=cm[(jj+kk)%k]; } had[ttmp]=true; } } R=0; for(int ii=L;ii<=128;++ii) if(had[ii]) { R=max(R,ii); flag=true; //BUG; } else break; ans=max(R,ans); } pre=true; while(next_permutation(c.begin(),c.end())) { cmlen=0; for(int ii=0;ii<c.size();++ii) cm[cmlen++]=c[ii]; //sort(d.begin(),d.end()); if(pre) { cmlen=c.size(); memset(had,false,sizeof had); for(int ii=0;ii<d.size();++ii) cm[cmlen++]=d[ii]; for(int ii=1;ii<=k;++ii) { for(int jj=0;jj<k;++jj) { ttmp=0; for(int kk=0;kk<ii;++kk) { ttmp^=cm[(jj+kk)%k]; } had[ttmp]=true; } } R=0; for(int ii=L;ii<=128;++ii) if(had[ii]) { R=max(R,ii); flag=true; //BUG; } else break; ans=max(R,ans); while(prev_permutation(d.begin(),d.end())) { //BUG; memset(had,false,sizeof had); cmlen=c.size(); for(int ii=0;ii<d.size();++ii) cm[cmlen++]=d[ii]; //for(int ii=0;ii<cmlen;++ii) //cout<<cm[ii]<<" "; //cout<<endl; for(int ii=1;ii<=k;++ii) { for(int jj=0;jj<k;++jj) { ttmp=0; for(int kk=0;kk<ii;++kk) { ttmp^=cm[(jj+kk)%k]; } had[ttmp]=true; } } R=0; for(int ii=L;ii<=128;++ii) if(had[ii]) { R=max(R,ii); flag=true; //BUG; } else break; ans=max(R,ans); } } else { cmlen=c.size(); memset(had,false,sizeof had); for(int ii=0;ii<d.size();++ii) cm[cmlen++]=d[ii]; for(int ii=1;ii<=k;++ii) { for(int jj=0;jj<k;++jj) { ttmp=0; for(int kk=0;kk<ii;++kk) { ttmp^=cm[(jj+kk)%k]; } had[ttmp]=true; } } R=0; for(int ii=L;ii<=128;++ii) if(had[ii]) { R=max(R,ii); flag=true; //BUG; } else break; ans=max(R,ans); while(next_permutation(d.begin(),d.end())) { //BUG; memset(had,false,sizeof had); cmlen=c.size(); for(int ii=0;ii<d.size();++ii) cm[cmlen++]=d[ii]; //for(int ii=0;ii<cmlen;++ii) //cout<<cm[ii]<<" "; //cout<<endl; for(int ii=1;ii<=k;++ii) { for(int jj=0;jj<k;++jj) { ttmp=0; for(int kk=0;kk<ii;++kk) { ttmp^=cm[(jj+kk)%k]; } had[ttmp]=true; } } R=0; for(int ii=L;ii<=128;++ii) if(had[ii]) { R=max(R,ii); flag=true; //BUG; } else break; ans=max(R,ans); } } } } } } if(flag) printf("%d ",ans); else puts("0"); } //fclose(stdin); //fclose(stdout); } /* 11 5 20 17 60 10 47 70 94 44 30 35 2 58 12 3 16 54 11 74 29 36 34 27 24 67 44 65 6 12 6 100 55 73 45 29 79 67 10 46 55 30 11 66 20 6 62 29 98 81 6 43 42 39 15 87 78 5 77 4 43 71 83 87 44 13 67 23 16 104 71 */