HDU——5014 Number Sequence

题目大意:给定一个数值n,并且[0,n]之间的n+1个数组成一个数列a,求出一个与之对应位的异或值之和最大的一个数列b,b取值为[0,n]。

解题思路:若使两个数a,b异或值最大,b只需满足异或之后将a的二进制位为0的位置变为为1,且b的二进制位的最高位不能超过a。

题目来源:点击打开链接

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
#define maxn 100001


int a[maxn],b[maxn];
long long ans;
int main()
{
    int n,t,j,res;
    while(~scanf("%d",&n))
    {
        ans = 0;
        memset(b,-1,sizeof(b));
        for(int i = 0; i <= n; i++)
        {
            scanf("%d",&a[i]);
            ans +=a[i];
        }
        ans<<=1;
        printf("%I64d\n",ans);
        for(int i = n; i >= 0; i--)//
        if(b[i] == -1)//
        {
            t = i, j = 1, res = 0;//首先对[0,n]之间的每个数求与之异或值最大的数值;
            while(t)//
            {
                if(t&1);//如果t为奇数,则证明此时的最高二进制位不为0;
                else
                res |= j;//当t为偶数时,证明1xj(j转换成2^k形式)的位置为0,此时要进行异或;
                j<<=1,t>>=1;//每次进行完异或运算后,t的二进制位就要向右移动一位,进行判定,而j要向左移动一位,等待填补空缺;
            }
            b[res] = i, b[i] = res;
        }
        for(int i = 0; i < n; i++)
        printf("%d ",b[a[i]]);
        printf("%d\n",b[a[n]]);
    }
    return 0;
}


以上分析也许不是很详细,毕竟还是菜鸟,望请谅解!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值