您的位置:首页 > 其它

USACO-Section2.1 Hamming Codes [搜索]

2017-07-16 17:36 369 查看

题目大意

给出 N,B 和 D,要求找出 N 个由0或1组成的编码(1 <= N <= 64),每个编码有 B 位(1 <= B <= 8),使得两两编码之间至少有 D 个单位的“Hamming距离”(1 <= D <= 7)。“Hamming距离”是指对于两个编码,他们二进制表示法中的不同二进制位的数目。看下面的两个编码 0x554 和 0x234(0x554和0x234分别表示两个十六进制数):

0x554 = 0101 0101 0100
0x234 = 0010 0011 0100
不同位    xxx  xx


因为有五个位不同,所以“Hamming距离”是 5。

格式

PROGRAM NAME: hamming

INPUT FORMAT:

(file hamming.in)

一行,包括 N, B, D。

OUTPUT FORMAT:

(file hamming.out)

N 个编码(用十进制表示),要排序,十个一行。如果有多解,你的程序要输出这样的解:假如把它化为2^B进制数,它的值要最小。

SAMPLE INPUT

16 7 3

SAMPLE OUTPUT

0 7 25 30 42 45 51 52 75 76

82 85 97 102 120 127

题解

在1到 2B 之间,递增的枚举开始的搜索点,然后用dfs()搜索第一次可以达到N个编码的集合。这题还是在练习位运算。可以用一个int来表示二进制编码,也可以用C++ STL的bitset。

下面给出两种实现:

代码1

不使用bitset

#include <iostream>
#include <fstream>
#include <cstring>
#include <bitset>
#define MAXN 70
#define MAXB 8
#define cin fin
#define cout fout
using namespace std;
ifstream fin("hamming.in");
ofstream fout("hamming.out");

int N, B, D, MAX;
int rel[MAXN];

int count(int x) {
int k = 1, cnt = 0;
for (int i = 0; i < B; i++) {
if (x & k) cnt++;
k <<= 1;
}
return cnt;
}

bool dfs(int step) {
if (step == N) {
for (int i = 0; i < step-1; i++) {
cout << rel[i];
cout << (i % 10 == 9 ? "\n" : " ");
}
cout << rel[step-1] << endl;
return true;
}
for (int i = 0; i < MAX; i++) {
bool flag = true;
for (int j = 0; j < step; j++) {
if (count(i ^ rel[j]) < D) {
flag = false;
break;
}
}
if (flag) {
rel[step] = i;
if (dfs(step+1)) return true;
}
}
return false;
}

int main() {
cin >> N >> B >> D;
memset(rel, 0, sizeof(rel));
MAX = 1 << B;
for (int i = 0; i < MAX; i++) {
rel[0] = i;
if (dfs(1)) break;
}
return 0;
}


代码2

使用bitset

//#include<iostream>
#include<fstream>
#include<bitset>
using namespace std;
ifstream cin("hamming.in");
ofstream cout("hamming.out");
int a[65], N, B, D, ans=1;
int dfs(int n, int pre);
int main()
{
cin >> N >> B >> D;
for(int i=0; i<(1<<B); i++)
{
a[0] = i;
if(dfs(N-1,0)) break;
}
cout << a[0] << " ";
for(int i=1; i<ans-1; i++)
{
cout << a[i];
if(!((i+1)%10)) cout << endl;
else cout << " ";
}
cout << a[ans-1] << endl;
return 0;
}
int dfs(int n, int pre)
{
if(n==0) return 1;
for(int i=a[pre]+1; i<(1<<B); i++)
{
bool ok = true;
for(int j=0; j<ans; j++)
{
bitset<9> bit(i^a[j]);
if(bit.count() < D)
{
ok = false;
break;
}
}
if(ok)
{
a[ans] = i;
if(dfs(n-1,++ans)) return 1;
}
}
ans--;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: