洛谷 P1461 海明码 Hamming Codes

一、题目描述

在这里插入图片描述

二、算法分析说明

数据比较少,暴力枚举即可。
为了使产生的编码的每个数都尽量小,从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;
}
发布了214 篇原创文章 · 获赞 19 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/COFACTOR/article/details/104124110