首页 > 代码库 > HDU 4876 ZCC loves cards

HDU 4876 ZCC loves cards

我决定记录下这么恶心的代码。比赛的时候头晕脑胀,写得好搓,错的地方好多好多,回来调了好久。。。。

做法大概就是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!~\n")#define mod 1000000007using 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\n",ans);        else puts("0");    }    //fclose(stdin);    //fclose(stdout);}/*11 5 2017 60 10 47 70 94 44 30 35 2 5812 3 1654 11 74 29 36 34 27 24 67 44 65 612 6 10055 73 45 29 79 67 10 46 55 30 11 6620 6 6229 98 81 6 43 42 39 15 87 78 5 77 4 43 71 83 87 44 13 67231610471*/