数据小,暴力搜索可以搞定。但是推荐使用DFS,每个节点(数)有取与不取两个分支。注意: 0是必须出现的。
证明如下:
最终得到的结果序列中,0是必须出现的,证明如下:
如果存在另一个满足要求的结果序列S={a1...an},其最小值为a1 = N > 0,
那么序列S' = S ^ N 是满足条件的最小解,且首元素为0
/*
ID: xpli1
PROG: hamming
LANG: C++
*/
#include <iostream>
#include <fstream>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;
#define OUT cout
#define IN cin
ofstream fout ("hamming.out");
ifstream fin ("hamming.in");
int N,B,D;
bool ham[256][256] = {false};
int res[65];
int dat[65];
int Max;
bool finded = false;
bool ham_dis(int a,int b){
int mask = a^b;
int dis = 0;
for(int i=0; i<B; i++){
dis += mask & 1;
mask >>= 1;
}
return dis < D ? false : true;
}
void init(){
int i,j;
Max = 1<<B;
for(i=0; i<Max-1; i++){
for(j=i+1; j<Max; j++){
ham[i][j] = ham_dis(i,j);
ham[j][i] = ham[i][j];
}
}
}
void dfs(int k,int dep){
if(finded) return;
if(k == N) {
finded = true;
memcpy(res,dat,65*sizeof(int));
return;
}
if(dep == Max) return;
int i;
for(i=0; i<k; i++){
if(!ham[dat[i]][dep]) break;
}
if(i==k){
dat[k] = dep;
dfs(k+1,dep+1);
dat[k] = 0;
}
dfs(k,dep+1);
}
void output(){
for(int i=0; i<N-1; i++){
if(i%10 == 9)
OUT << res[i] << endl;
else OUT << res[i] << ' ';
}
OUT << res[N-1] << endl;
}
int main()
{
IN >> N >> B >> D;
init();
dfs(0,0);
output();
return 0;
}