hdu 5014(贪心+异或 西安网络赛)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5014

Number Sequence

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)

Total Submission(s): 681    Accepted Submission(s): 321

Special Judge

Problem Description

There is a special number sequence which has n+1 integers. For each number in sequence, we have two rules:

● ai ∈ [0,n]

● ai ≠ aj( i ≠ j )

For sequence a and sequence b, the integrating degree t is defined as follows(“⊕” denotes exclusive or):

t = (a0 ⊕ b0) + (a1 ⊕ b1) +···+ (an ⊕ bn)

(sequence B should also satisfy the rules described above)

Now give you a number n and the sequence a. You should calculate the maximum integrating degree t and print the sequence b.

Input

There are multiple test cases. Please process till EOF.

For each case, the first line contains an integer n(1 ≤ n ≤ 105), The second line contains a0,a1,a2,...,an.

Output

For each case, output two lines.The first line contains the maximum integrating degree t. The second line contains n+1 integers b0,b1,b2,...,bn. There is exactly one space between bi
and bi+1(0 ≤ i ≤ n - 1). Don’t ouput any spaces after bn.

Sample Input

4
2 0 1 4 3

Sample Output

20
1 0 2 3 4

Source

2014 ACM/ICPC Asia Regional Xi‘an Online

思路: 网上已经有很多解题报告了,解法都差不多,给定一个数n,求这n+1个数与另外n+1个数相匹配求最大的异或值之和;

可以发现规律: 从n开始遍历到0,让每个值都找到另一个“互补”的值,比如 :n=9,那么就有10个数,最大的是9,其二进制表示为1001,那么它就应该与0110匹配~

(一定得从最大值n开始遍历,才符合贪心的正确性)

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <string>
#include <cstdio>
#include <cmath>
const int N=1e5+100;
using namespace std;
int hash[N];
int a[N];

int main()
{
    int n;
    while(cin>>n)
    {
      for(int i=1;i<=n+1;i++)
      {
        scanf("%d",&a[i]);
      }
      memset(hash,-1,sizeof(hash));
      for(int i=n;i>=0;i--) //将n个数从大到小排列进行位处理,使得“互补”,这样异或值才是最大的;
      {
       if(hash[i]>-1)continue;
       int sum=0,cnt=1,s=i;
       while(s)
       {
         int t=(s&1)^1;
         sum+=t*cnt;
         cnt*=2;
         s/=2;
       }

       hash[i]=sum;
       hash[sum]=i;
      }
      printf("%I64d\n",(long long )n*n+n);
      for(int i=1;i<=n+1;i++)
      {
        if(i==1)printf("%d",hash[a[i]]);
        else printf(" %d",hash[a[i]]);
      }
      printf("\n");
    }
    return 0;
}
时间: 2024-10-15 04:20:15

hdu 5014(贪心+异或 西安网络赛)的相关文章

HDU 5014 Number Sequence(西安网络赛H题)

HDU 5014 Number Sequence 题目链接 思路:对于0-n,尽量不让二进制中的1互相消掉就是最优的,那么只要两个数只要互补就可以了,这样每次从最大的数字,可以找到和他互补的数字,然后这个区间就能确定了,然后剩下的递归下去为一个子问题去解决 代码: #include <cstdio> #include <cstring> const int N = 100005; int n, a[N], ans[N]; int cnt[N]; int count(int x) {

hdu 5014 Number Sequence(西安网络赛1008)

Number Sequence                                                                  Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 633    Accepted Submission(s): 300 Special Judge Problem Descrip

HDU 5009 Paint Pearls(西安网络赛C题) dp+离散化+优化

转自:http://blog.csdn.net/accelerator_/article/details/39271751 吐血ac... 11668627 2014-09-16 22:15:24 Accepted 5009 1265MS 1980K 2290 B G++ czy   Paint Pearls Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Subm

HDU 5015 233 Matrix(西安网络赛I题)

HDU 5015 233 Matrix 题目链接 思路:矩阵快速幂,观察没一列,第一个和为左边加最上面,第二个可以拆为左边2个加最上面,第三个可以拆为为左边3个加最上面,这样其实只要把每一列和每一列右边那列的233构造出一个矩阵,进行矩阵快速幂即可 代码: #include <cstdio> #include <cstring> typedef long long ll; const int N = 15; const int MOD = 10000007; int n, m; s

HDU 5009 Paint Pearls(西安网络赛C题)

HDU 5009 Paint Pearls 题目链接 题意:给定一个目标颜色,每次能选一个区间染色,染色的代价为这个区间不同颜色数的平方,问最小代价 思路:先预处理,把相同颜色的一段合并成一个点,然后把颜色离散化掉,然后进行dp,dp[i]表示染到第i个位置的代价,然后往后转移,转移的过程记录下不同个数,这样就可以转移了,注意加个剪枝,就是如果答案大于了dp[n]就不用往后继续转移了 代码: #include <cstdio> #include <cstring> #include

hdu 5015 233 Matrix(西安网络赛1009)【构造矩阵】

说起这题简直醉了..当时愣是没想到该怎么做,搞了好久,虽然有想过构造矩阵,但是没仔细想下去. 此题构造两个矩阵,假设a[]数组为题目给出的数据,最多有10个元素,我们可以构造一个矩阵A: a={a[1],a[2],a[3],...a[n],23,3}  大小为1*(n+2) 要得到题目需要的计算结果,那么在构造一个矩阵B,大小为(n+2)*(n+2):(假设n=3) b=   1    1    1    0    0 0    1    1    0    0 0    0    1    0

hdu5017:补题系列之西安网络赛1011

补题系列之西安网络赛1011 题目大意:给定一个椭球: 求它到原点的最短距离. 思路: 对于一个椭球的标准方程 x^2/a^2 + y^2/b^2 +z^2/c^2=1 来说,它到原点的最短距离即为min(a,b,c) 所以我们需要把原方程化为标准型. 这时候线代就排上用场了,注意到原方程是一个二次型. 化为标准型 1/(k1)*x^2+1/(k2)*y^2+1/(k3)*z^2=1 后  min(k1,k2,k3)即为答案 而这里的1/k1,1/k2,1/k3 就是二次型矩阵的特征值 如何求特

HDU 5008西安网络赛B题:后缀数组求第k小子串

思路:尼玛,这题搞了一天了,比赛的时候用了n^2的方法绝对T了,然后今天看别人代码看了一天才知道.后面感觉也挺容易的,就是没想到,之前做过SPOJ 694 705求过不同子串了,知道怎么求不同子串个数了,但是比赛的时候这个技巧竟然抛在脑后了,然后就不会了. 但是今天自己用了自己的两个后缀数组的模板(倍增和DC3)的都WA了,搞得自己真想跳楼去了!! 到现在都不知道到底是哪里错了,处理的方法和标准做法都一样,但是就是WA,然后用了别人的模板,再用自己的处理方法就过了,怀疑自己的两个模板是不是哪里错

hdu 6152 : Friend-Graph (2017 CCPC网络赛 1003)

题目链接 裸的结论题.百度 Ramsey定理.刚学过之后以为在哪也不会用到23333333333,没想到今天网络赛居然出了.顺利在题面更改前A掉~~~(我觉得要不是我开机慢+编译慢+中间暂时死机,我还能再早几分钟过掉它 #include<bits/stdc++.h> using namespace std; int g[8][8]; int n; void solve() { for(int i=1; i<=n; i++) for(int j=i+1; j<=n; j++) for