Number Sequence (思维,二进制)

题目来源:https://vjudge.net/problem/HDU-5014
【题意】
给出一个n,外加一个0-n无序序列(n+1个数),给出一个公式:
t=a[0]^b[0]+a[1]^b[1]+…+a[n]^b[n],让求t的最大值,其中b数组
也是从0-n,不过顺序的话是随意的,只要让t最大就行。
【思路】
异或,想到二进制,怎么使a[i]^b[i]最大,想到补位(纯属个人造词),
举个例子,10的二进制是1010,如果使他最大为1111,那么需要5,也就是101来进行补位。
分析样例,4 2 0 1 4 3,那么他们的二进制是 10 0 1 100 11,
从大到小依次替换,b序列是 1 0 10 11 100,刚好符合样例。
【代码】

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<cmath>
#include<map>
#include<queue>
using namespace std;
typedef long long LL;
int a[100004];
int b[100004];
bool v[100004];
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        memset(v,0,sizeof(v));
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        for(int i=0; i<=n; i++)
            scanf("%d",&a[i]);
        for(int i=n; i>=0; i--)//从大到小依次替换
        {
            if(!v[i])//判断有没有被替换过
            {
                int pp=1,c,w=0,p=i;
                while(p)//根据其二进制求其相应的数
                {
                    c=p%2;p/=2;
                    if(!c) w+=pp; pp*=2;
                }
                v[i]=v[w]=1; b[i]=w;b[w]=i;//标记+替换
            }
        }
        LL tmax=0;
        for(int i=0; i<=n; i++)
            tmax+=(LL)(a[i]^b[a[i]]);
        printf("%lld\n",tmax);
        printf("%d",b[a[0]]);
        for(int i=1; i<=n; i++)
            printf(" %d",b[a[i]]);
        printf("\n");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值