牛客dfs

在一组数的编码中,若任意两个相邻的代码只有一位二进制数不同,则称这种编码为格雷码(Gray Code),另外由于第一个与最后一个之间也仅一位数不同,即“首尾相连”,因此又称循环码或反射码。

例如一段比较经典的格雷码就是:

0 1 3 2 6 7 5 4

小沙有一段自己的编码数列,他发现他的编码数列与格雷码很像,它的任意两个相邻的编码只有一位二进制数不同,但是它的第一个与最后一个之间不一定仅有一位数不同。


现在小沙给出在他编码意义下所有小于�n的偶数位在普通编码十进制的值,需要你猜想小沙编码意义下 [0,�−1][0,n−1] 在普通编码十进制的值。

题目保证 �=2�n=2k , �k 为一个正整数,你需要保证你猜想的数字 �x ,0≤�<�0≤x<n。
 

输出任意合法方案皆可,保证存在一个合法方案。

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>

using namespace std;
const int N = 1e5+10;
int n,flag;
int vis[N];
vector<int> res;
vector<int> q[N];
int calu(int x){
    int cnt=0;
    while(x){
        cnt++;
        x-=x&-x;
    }
    return cnt;
}
void dfs(int cnt){
    if(res.size()==n/2){
        flag=1;
        return ;
    }
    for(int i=0;i<q[cnt].size();i++){
        if(vis[q[cnt][i]]) continue;
        res.push_back(q[cnt][i]);
        vis[q[cnt][i]]=1;
        dfs(cnt+1);
        vis[q[cnt][i]]=0;
        if(flag) return ;
        res.pop_back();
    }
}
int main()
{
    cin>>n;
    int maxs=log2(n)-1,cnt=0;
    vector<int> g(n/2+1);
    for(int i=1;i<=n/2;i++) cin>>g[i];
    for(int i=2;i<=n/2;i++){
        for(int j=0;j<=maxs;j++){
            int ans=g[i-1]^(1<<j);
            if(calu(g[i]^ans)==1){
                q[cnt].push_back(ans);
            }
        }
        cnt++;
    }
    for(int i=0;i<=maxs;i++){
        int ans=g[n/2]^(1<<i);
        q[cnt].push_back(ans);
    }
    dfs(0);
    cnt=0;
    for(int i=1;i<=n/2;i++)
    cout<<g[i]<<" "<<res[cnt++]<<" ";
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值