您的位置:首页 > 编程语言 > PHP开发

USACO :Hamming Codes 解题报告

2010-04-23 16:50 483 查看
数据小,暴力搜索可以搞定。但是推荐使用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;

}

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  output c