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的情况下 二进制的状态
int n, k, l;
int a[21], d[6], val[6];
int vis[150], tim;
int work(int x){
    int i = 0, j = 0;
    while(x) {
        if(x&1)    d[i++] = j;//a[j]
        j++;
        x>>=1;
    }
    int ans = 0;
    do
    {
        memset(val, 0, sizeof val);
        tim ++;
        int st = 0;
        for(int num = 0; num < k; num++) {
            i = st; j = 0;
            while(1) {
                val[j] ^= a[d[i]];
                vis[val[j]] = tim;
                i++; j++;if(i>=k)i=0;
                if(i==st)break;
            }
            st++;
        }
        for(i = l; ; i++)
            if(vis[i]!=tim)
            {
                ans = max(ans, (i-1)>=l? (i-1):0);
                break;
            }
    } while (next_permutation(d + 1, d + k));
    return ans;
}
void dfs(int dep, int cnt, int num) {
    if (dep > 20 || cnt > 6) return ;
    G[dep][cnt].push_back(num);
    dfs(dep + 1, cnt + 1, num | (1 << dep));
    dfs(dep + 1, cnt, num);
}

struct Node {
    int cnt, idx;
    bool operator < (const Node &rhs) const {
        return cnt > rhs.cnt;
    }
};

Node qq[24];
int b[24];

int cmp(int a, int b) {
    return a > b;
}

int main(){
    int i, j;
    for(i = 1; i <= 20; i++)
        for(j = 1; j <= 6; j++) G[i][j].clear();
    dfs(0, 0, 0);
    tim = 100;
    while(~scanf("%d %d %d",&n, &k, &l)) {
        for(i = 0; i < n; i++)scanf("%d",&a[i]);

        int ans = 0, siz = (int)G[n][k].size();
        if (siz <= 12000) {
            for (int i = 0; i < siz; ++i) {
                int cur = G[n][k][i];
                ans = max(ans, work(cur));
              }
        } else if (siz <= 24001) {
            for (int i = 1; i < siz; i += 2) {
                int cur = G[n][k][i];
                ans = max(ans, work(cur));
            }
        } else {
            for (int i = 0; i < siz; i += 3) {
                int cur = G[n][k][i];
                ans = max(ans, work(cur));
            }
        }

        printf("%d\n",ans);
    }
    return 0;
}

HDU 4876 ZCC loves cards _(:зゝ∠)_ 随机输出保平安,布布扣,bubuko.com

时间: 2024-11-03 21:27:14

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> #

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 4937 Lucky Number 规律题_(:зゝ∠)_

把所有合法的进制打出来会发现合法的进制都是在 n/3 n/4 n/5的边上 然后暴力边上的进制数.. #include <cstdio> #include <set> typedef long long ll; bool ok(ll x, ll y) { ll v; while (x > 0) { v = x % y; if (v != 3 && v != 4 && v != 5 && v != 6) return false;

HDU 4941 Magical Forest _(:зゝ∠)_ 模拟题

模拟大法保平安_(:зゝ∠)_ #include <cstdio> #include <map> #include <set> #include <algorithm> using namespace std; const int N = 1; struct node{ int x, y, val; node(int a=0,int b=0,int c=0):x(a),y(b),val(c){} bool operator<(const node&am

HDU 4915 Parenthese sequence _(:зゝ∠)_ 呵呵

呵呵不是我做的 #include <cstdio> #include <cstring> #include <algorithm> const int N = 1000000 + 10; char s[N]; int d[N], num[N]; int main() { while (~scanf("%s", s)) { memset(num, 0, sizeof num); int len = strlen(s); int f = 1, v = 0