一、题目描述
二、算法分析说明
数据比较少,暴力枚举即可。
为了使产生的编码的每个数都尽量小,从0开始进行枚举。0肯定是需要添加到编码中的。
每个编码长b位,枚举范围就是0到2的b次方减1。
对两个数进行按位异或运算,如果对应的位相同,则结果的对应位为0,否则为1。
两个数的Hamming距离就是把这两个数转成二进制以后对应位的值不同的位数。
异或以后要统计1的数量。可以对数反复与1进行按位与,因为1的二进制只有最低位是1,其余位都是0,所以按位与以后其它位都是0。&1以后,如果这个数的最低位是1,结果就是1。最低位是0,结果就是0。要判断其它位是否为1,就将这个数右移1位,然后按位与即可,直到数为0。
统计异或的结果有多少个1(二进制下),就得到两个数的Hamming距离。
如果正在判断的数与编码中以后的数的Hamming距离都不小于d,这个数就要添加到编码中。编码有n个数时,退出循环。
三、AC 代码
#include<cstdio>
#include<vector>
#pragma warning(disable:4996)
using namespace std;
vector<unsigned> v; unsigned n, b, d, c, t; bool ok;
inline unsigned hamming_dist(const unsigned& a, const unsigned& b) {
unsigned c = a ^ b, d = 0;
while (c != 0) {
d += c & 1;
c >>= 1;
}
return d;
}
int main() {
scanf("%u%u%u", &n, &b, &d);
v.emplace_back(0);
while (v.size() != n) {
++c; ok = true;
for (size_t i = 0; i < v.size(); ++i) {
if (hamming_dist(v[i], c) < d) { ok = false; break; }
}
if (ok == true)v.emplace_back(c);
}
for (size_t i = 0; i < v.size(); ++i) {
if (i != 0 && i % 10 == 0)putchar('\n');
printf("%u ", v[i]);
}
return 0;
}