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 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\n",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
*/

HDU 4876 ZCC loves cards,布布扣,bubuko.com

时间: 2024-12-21 23:27:01

HDU 4876 ZCC loves cards的相关文章

HDU 4876 ZCC loves cards _(:зゝ∠)_ 随机输出保平安

GG,,,g艹 #include <cstdio> #include <iostream> #include <algorithm> #include <string.h> #include <vector> #include <queue> #include <math.h> using namespace std; vector<int>G[21][7];//G[i][j] 表示n=i k=j的情况下 二进

hdu 4876 ZCC loves cards(暴力)

题目链接:hdu 4876 ZCC loves cards 题目大意:给出n,k,l,表示有n张牌,每张牌有值.选取其中k张排列成圈,然后在该圈上进行游戏,每次选取m(1≤m≤k)张连续的牌,取牌上值的亦或和.要求找到一个圈,使得L~R之间的数都可以得到,输出R.如果R < L输出0. 解题思路:暴力,首先预处理出来每种选取的亦或值,然后在该基础上从可以组成L的状态中挑选一个,L+1的状态中挑取一个,知道说总的挑取出所有状态中选中的牌的个数大于K为值,然后用全排序去查找最大的R. #includ

HDU 4876 ZCC loves cards(暴力剪枝)

HDU 4876 ZCC loves cards 题目链接 题意:给定一些卡片,每个卡片上有数字,现在选k个卡片,绕成一个环,每次可以再这个环上连续选1 - k张卡片,得到他们的异或和的数,给定一个L,问能组成[L,R]所有数字的情况下,R的最大值是多少 思路:暴力C(20, 6),然后对于每个序列去全排后模拟计算值, 不过之前要有个剪枝,全排前,先把k个数随机取数(即不用连续),然后如果这样还满足不了,那么连续的情况肯定也满足不了,直接结束,不进入全排.这样一来由于满足不了的情况实际上是占绝大

HDU 4876 ZCC loves cards【暴力+深搜+剪枝】

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4876 题意:给你N,l,k三个数,N代表N个数,从中任选k个数,然后 这k个数组成一个环,可以从这个环中选连续的1-k个数进行异或和 ,把所得到的值填充到l的后面,使得有一个数r让l-r之间所有的整 整数都被这些异或和填满,求最大的r,也许表达的不太清楚,其实 就是找一个最大的r,使得给定的l到这个r之间所有的数都能够被这些 异或和表示出来,注意异或和要求是连续的数异或的和. 分析:这道题我看了好久

HDU 4876 ZCC loves cards 暴力+剪枝

题意:n张牌,选k个排成一圈,给出L,求出最大R 使得[L,R]内任意一个数 都可以由圈内连续m个数异或得到.n<=20,k<=6,a[i],L<=100. m为自己设定的. 暴力 总共有A(20,6)种方案 每种方案k^2算出异或数 TLE..先C(20,6)选出方案 若能过最优性剪支,在全排列更新答案. 注意先将a排序 使得全排列从最小序开始. #include <bits/stdc++.h> using namespace std; typedef long long

HDOJ 4876 ZCC loves cards

枚举组合,在不考虑连续的情况下判断是否可以覆盖L...R,对随机数据是一个很大的减枝. 通过检测的暴力计算一遍 ZCC loves cards Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 1346    Accepted Submission(s): 335 Problem Description ZCC loves playing

HDU 4873 ZCC Loves Intersection(JAVA、大数、推公式)

在一个D维空间,只有整点,点的每个维度的值是0~n-1 .现每秒生成D条线段,第i条线段与第i维度的轴平行.问D条线段的相交期望. 生成线段[a1,a2]的方法(假设该线段为第i条,即与第i维度的轴平行)为,i!=j时,a1[j]=a2[j],且随机取区间[0,n-1]内的整数.然后a1[i],a2[i]在保证a1[i]<a2[i]的前提下同样随机. 由于D条线段各自跟自己维度的轴平行,我们可以转换成只求第i个维度与第j个维度的相交期望,然后乘以C(2,n)就好了 显然线段[a1,a2]和线段[

hdu 4882 ZCC Loves Codefires(数学题+贪心)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4882 ---------------------------------------------------------------------------------------------------------------------------------------------------------- 欢迎光临天资小屋:http://user.qzone.qq.com/593830943

hdu 4882 ZCC Loves Codefires(贪心)

# include<stdio.h> # include <algorithm> # include <string.h> using namespace std; struct node { int v; int t; }; struct node a[100010]; bool cmp(node a,node b) { return a.v *a.t+(a.v+b.v)*b.t<b.v*b.t+(a.v+b.v)*a.t; } int main() { int