【USACO 2.1.5】海明码

【题目描述】

给出 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进制数,它的值要最小。

【分析】

直接一个一个枚举就行了。

注意:必须与其他所有的数相比,Hamming距离都符合要求,这个数才正确 ,如样例输出,0和7,0和25,0和……比较都符合海明码,同样7和25,7和30,7和……比较也符合要求,以此类推。

 1 #include <cstdlib>
 2 #include <iostream>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <cmath>
 6 #include <queue>
 7 #include <algorithm>
 8 using namespace std;
 9 int ans[70];
10 int N,B,D;
11 int check(int a,int b);
12 int main()
13 {
14     int i,j,point;
15     //文件操作
16     freopen("hamming.in","r",stdin);
17     freopen("hamming.out","w",stdout); 
18     scanf("%d%d%d",&N,&B,&D);
19     ans[1]=0;i=1;point=2;//指针 
20     while (point!=(N+1))
21     {
22           for (i=i;i<=(1<<B)-1;i++)
23           {
24               for (j=1;j<point;j++) if (check(ans[j],i)<D) goto w;
25               break;//满足条件的i应该退出
26               w:continue; 
27           }
28           ans[point++]=i;
29     }
30     j=0;
31     for (i=1;i<point;i++) 
32     {
33         j++;
34         if (j==11) {j=1;printf("\n");}
35         printf("%d ",ans[i]);
36     } 
37     return 0;
38 }
39 int check(int a,int b)
40 {
41     int cnt=0,i;
42     for (i=0;i<B;i++) if ((a&(1<<i))!=(b&(1<<i))) cnt++;
43     return cnt;
44 }

 

posted @ 2014-06-14 21:23  TCtower  阅读(412)  评论(0编辑  收藏  举报