USACO-Section2.1 Hamming Codes [搜尋]
阿新 • • 發佈:2019-02-07
題目大意
給出 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;
}