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!~
")
#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
*/
原文地址:https://www.cnblogs.com/morimiya/p/3867723.html