hdu 5014 Number Sequence 找规律 | 贪心 2014 ACM/ICPC Asia Regional Xi'an Online

来源:互联网 发布:男士便宜单肩包 知乎 编辑:程序博客网 时间:2024/05/01 14:43

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

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
42 0 1 4 3
 

Sample Output
201 0 2 3 4
 

Source
2014 ACM/ICPC Asia Regional Xi'an Online


线下 AC的,比赛的时候其实已经找到规律了,然后自己二呵呵的把binary数组初值赋错了,一直没发现....粗糙党

不过后来看正解是贪心...但我们的规律也是按贪心找的...

思路:

     如果两个数的二进制位数不同,这两个数的异或值就会越大,所以尽量使   a^b == 2^x - 1,这样我们得到了一个基本关系。

  

a:   0  1  2  3  4   5  6  7  8  9  10 11  12  13  14  15  16 17 ...
b:   0  2  1  4  3  10  9  8  7  6  5  20  19  18  17  16  15 14 ...

可以看出从17~11是递增,10~5也是递增的,4~3是递增的,2~1递增,如果a是上限,那么直接找2^x - 1 >= a,这里=a ,只有第一次累加的时候,然后一次往回加,加到小于上一次的最小值....重复这个过程...我用了low和high来完成累加的过程,并标记每一次的上下限

代码:

#include <algorithm>#include <cstdlib>#include <iostream>#include <cstring>#include <cstdio>#include <vector>#include <cctype>#include <cmath>#include <stack>#include <queue>#include <list>#include <map>#include <set>using namespace std;#define min2(x, y)     min(x, y)#define max2(x, y)     max(x, y)#define min3(x, y, z)  min(x, min(y, z))#define max3(x, y, z)  max3(x, max(y, z))#define clr(x, y)      memset(x, y, sizeof(x))#define fr(i,n)        for(int i = 0; i < n; i++)#define fr1(i,n)       for(int i = 1; i < n; i++)#define upfr(i,j,n)    for(int i = j; i <= n; i++)#define dowfr(i,j,n)   for(int i = n; i >= j; i--)#define scf(n)         scanf("%d", &n)#define ptf(n)         printf("%d",n)#define ptfl(n)        printf("%I64d",n)#define ptfs(s)        printf("%s",s)#define ptk()          printf(" ")#define ptln()         printf("\n")#define srt(a,n)       sort(a,n)#define LL long long#define pi acos(-1.0)#define inf 1 << 31-1#define eps 0.00001#define maxn 100005int arr[maxn];int ans[maxn];int binary[maxn];int vis[maxn];int main(){    //freopen("in.txt","r",stdin);    binary[0] = 1;    //2的0次是1,开始自己写成2了,2333    fr1(i,20)    binary[i] = binary[i-1] * 2;    int n;    while(scf(n) !=EOF )    {        clr(vis,0);        clr(ans,0);        clr(arr,0);        fr(i,n+1)        scf(arr[i]);        int tmp;        fr(i,20)        {            if(binary[i] > n)                {                    tmp = binary[i];                    break;                }        }        //ptf(tmp);        int low,high;        low = tmp - 1 - n;        ans[n] = low;        high = n;        dowfr(i,0,n-1)        {            if(ans[i+1]+1 == n)                ans[i] = n;            else if(ans[i+1] + 1 < high)                ans[i] = ans[i+1] + 1;            else            {                fr(j,20)                {                    if(binary[j] > i)                    {                        high = low ;                        low = binary[j] - 1 - i;                        break;                    }                }                ans[i] = low;            }        }        __int64 sum = 0;        fr(i,n+1)        sum += i ^ ans[i];        ptfl(sum);        ptln();        ptf(ans[arr[0]]);        upfr(i,1,n)           ptk(),ptf(ans[arr[i]]);        ptln();    }    return 0;}


0 0