一、算法分析
题目的关键在于,对于所找出的编码,任两两编码之间都至少有 d 个单位的 “Hamming距离”。解决方案即从起始数0开始,进行编码生成(实则就是从0开始枚举十进制数1,2,3,4…并转换为二进制数)。然后将生成的编码和前面的编码一一比较,只要保证当前生成编码和前面任一编码的hamming距离都大于等于d,则最后所有的编码都是满足条件的。这里求算hamming距离的方法,可以联系树状数组的lowbit,具体看代码。
二、代码与分析
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
#include<map>
#include<cmath>
#define ll long long
using namespace std;
int n,b,d;
int hamming(int x1,int x2){
int k=x1^x2;
int ans=0;
while(k>0){
ans++;
k-=k&(-k); //k&(-k)可以去掉k最右边的1的左边部分,而再用k减去k&(-k)就可以去掉k的最后一个1
}
return ans;
}
vector<int> ans;
int main(){
cin>>n>>b>>d;
int x=0; //当前编码的十进制数
int maxx=pow(2,b)-1; //因为规定了每个编码是b位,就相当于给出了枚举上界了
ans.push_back(x);
while(x<maxx){
x++;
int len=ans.size();
if(len==n) break;
int ok=1;
for(int i=0;i<len;i++){
if(hamming(ans[i],x)<d){
ok=0;
break;
}
}
if(ok) ans.push_back(x);
}
int len=ans.size();
for(int i=0;i<len;i++){
cout<<ans[i];
if((i+1)%10==0) cout<<endl;
else cout<<' ';
}
return 0;
}