Number Sequence

来源:互联网 发布:linux有文件夹进不去 编辑:程序博客网 时间:2024/06/07 07:25

从大到小处理所有的数,对每个数找与其对应的另一个数,找与其匹配的数用构造的方法,比如当前数的二进制位是1001011,则与其匹配的数的二进制应该是0110100,若构造出来的这个数不合法(即大于n或之前已经被别的数匹配过),则将这个数的二进位的最高位的1变成0,如上例则变成0010100。

#include <iostream>#include<cstdio>#include<cstring>#define ll long longusing namespace std;int a[100005],b[100005];bool vis[100005];int mp[100005];int main(){    int n;    while(~scanf("%d",&n))    {        memset(vis,0,sizeof(vis));        memset(mp,0,sizeof(mp));        int i,k=0,tmp=0;        ll t=0;        while(n>>k){            tmp |= 1<<k;            k++;        }        for(i=0;i<=n;i++) scanf("%d",&a[i]);        for(i=n;i>=0;i--){            if(!vis[i]){                int tt=(~i)&tmp;                while(tt>n){                    int wei=0;                    while(tt>>wei){                        wei++;                    }                    tt ^= 1<<(wei-1);                }                while(vis[tt]){                    int wei=0;                    while(tt>>wei){                        wei++;                    }                    tt ^= 1<<(wei-1);                }                vis[tt]=1;                mp[i]=tt;                mp[tt]=i;                vis[i]=1;            }        }        for(i=0;i<=n;i++){            b[i]=mp[a[i]];            t+=b[i]^a[i];        }        printf("%I64d\n",t);        for(i=0;i<=n;i++)        {            printf("%d",b[i]);            if(i!=n) printf(" ");        }        printf("\n");    }    return 0;}


0 0
原创粉丝点击