题目描述
给出 n,b,d,要求找出 n 个由 0,10,1 组成的编码,每个编码有 b 位),使得两两编码之间至少有 d 个单位的 “Hamming距离”。“
Hamming距离”是指对于两个编码,他们二进制表示法中的不同二进制位的数目。看下面的两个编码 0x554
和 0x234
(十六进制数)
0x554 = 0101 0101 0100
0x234 = 0010 0011 0100
不同位 xxx xx
因为有五个位不同,所以“Hamming距离”是 55。
输入格式
一行,包括 n,b,d。
输出格式
n 个编码(用十进制表示),要排序,十个一行。
如果有多解,你的程序要输出这样的解:假如把它化为2b 进制数,它的值要最小。
输入输出样例
输入 #1
16 7 3
输出 #1
0 7 25 30 42 45 51 52 75 76 82 85 97 102 120 127
说明/提示
【数据范围】
对于 100%100% 的数据,1≤n≤64,1≤b≤8,1≤d≤7。
请解释:“必须与其他所有的数相比,Hamming 距离都符合要求,这个数才正确”
答:如样例输出,0,70,7,0,250,25,比较都符合海明码,同样 7,257,25,7,307,30,比较也符合要求,以此类推。题中至少有 d 个单位,意思就是大于等于 d 个单位的都可以。
USACO 2.1
翻译来自NOCOW
#include<bits/stdc++.h>
using namespace std;
const int N=30;
int n,b,d,x,t,z,ans[70];
bool check(int a,int b){
int c=a^b;
int cnt=0;
while(c>0){
if((c&1)==1) cnt++; //c%2==1
c>>=1; //c/=2;
}
if(cnt>=d) return 1;
else return 0;
}
bool pd(int x){
for(int i=1;i<=t;++i)
if(check(x,ans[i])==0) return 0;
return 1;
}
int main(){
cin>>n>>b>>d;
ans[1]=0;
x=0;
t=1;
while(1){
++x;
if(pd(x)==1){
ans[++t]=x;
if(t==n) break;
}
}
for(int i=1;i<=t;++i){
printf("%d ",ans[i]);
if(i%10==0) printf("\n");
}
return 0;
}