hdu5014——构造打表找规律

 

题意给你一个序列,1---n,你安排另一个1---n的序列顺序,使得按位异或最后加起来和最大。。那么就是贪心高位,也就是从后往前了。

 

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;

int a[100005];
int b[100005];
int n;

int fin(int x){
    int temp=0;
    int ret=0;
    int i=0;
    while(x){
        temp=((x&1)^1);
        ret=(temp<<i)+ret;
        ++i;
        x/=2;
    }
    if(b[ret]==-1){
        return ret;
    }
    else{
        return -1;
    }
}

void init(){
    for(int i=n-1;i>0;i--){
        if(b[i]!=-1)
            continue;
        int x=fin(i);
        if(x!=-1){
            b[i]=x;
            b[x]=i;
        }
    }
    return;
}

int main(){
    while(cin>>n){
        n++;
        memset(b,-1,sizeof(b));
        for(int i=0;i<n;i++){
            scanf("%d",&a[i]);
        }
        init();
        long long ans=0;
        if(n%2==1)
            b[0]=0;
        for(int i=0;i<n;i++){
            ans+=(a[i]^b[a[i]]);
        }
        cout<<ans<<endl;
        for(int i=0;i<n;i++){
            if(i!=n-1)
                printf("%d ",b[a[i]]);
            else
                printf("%d\n",b[a[i]]);
        }
    }
    return 0;
}


这题做的时候略坑了。。。一眼看出贪心然后发现又遇到了问题,一下写不出来了。。第二天吧n是偶数的时候用next_permutation打表爽了一下。发现n是偶数的时候0异或0剩下贪心一下依旧是,于是从后往前贪心一下,按位取反一下,用到   ((x&1)^1)    再把每次新求到的位放到前面就行了   。代码如下:

 

posted @ 2016-03-23 21:02  zhangxianlong  阅读(148)  评论(0编辑  收藏  举报