【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 }