海 明 码 H a m m i n g C o d e s 海明码 Hamming Codes 海明码 Hamming Codes
题目链接:luogu P1461
题目
给出
N
N
N,
B
B
B 和
D
D
D,要求找出
N
N
N 个由
0
0
0或
1
1
1组成的编码,每个编码有
B
B
B 位,使得两两编码之间至少有
D
D
D 个单位的
“
H
a
m
m
i
n
g
距
离
”
“Hamming距离”
“Hamming距离”。
“
H
a
m
m
i
n
g
距
离
”
“Hamming距离”
“Hamming距离”是指对于两个编码,他们二进制表示法中的不同二进制位的数目。
看下面的两个编码
0
0
0x
554
554
554 和
0
0
0x
234
234
234(
0
0
0x
554
554
554和
0
0
0x
234
234
234分别表示两个十六进制数)
0x554 = 0101 0101 0100
0x234 = 0010 0011 0100
不同位 xxx xx
因为有五个位不同,所以 “ H a m m i n g 距 离 ” “Hamming距离” “Hamming距离”是 5 5 5。
输入
一行,包括 N N N, B B B, D D D。
输出
N N N 个编码(用十进制表示),要排序,十个一行。如果有多解,你的程序要输出这样的解:假如把它化为 2 B 2^B 2B进制数,它的值要最小。
样例输入
16 7 3
样例输出
0 7 25 30 42 45 51 52 75 76
82 85 97 102 120 127
题目解释
请解释:“必须与其他所有的数相比, H a m m i n g 距 离 Hamming距离 Hamming距离都符合要求,这个数才正确”
答:如样例输出, 0 0 0和 7 7 7, 0 0 0和 25 25 25, 0 0 0和……比较都符合海明码,同样 7 7 7和 25 25 25, 7 7 7和 30 30 30, 7 7 7和……比较也符合要求,以此类推。 就这样了。 题中至少有 D D D个单位,意思就是大于等于 D D D个单位的都可以。
数据范围
1
<
=
N
<
=
64
1 <= N <= 64
1<=N<=64
1
<
=
B
<
=
8
1 <= B <= 8
1<=B<=8
1
<
=
D
<
=
7
1 <= D <= 7
1<=D<=7
思路
这道题就是一道位运算。
枚举每一个数,看是不是海明码(根据前面的海明码),是的话就标记下来并输出,在处理一下换行就可以了。
代码
#include<cstdio>
using namespace std;
int n,b,d,h,H[65];
bool yes;
bool ch(int x,int y)
{
int di=0;//初始化
for (int i=1;i<=8;i++)//枚举每一位
if (((x^y)>>(i-1))&1)//是否不同
di++;//统计
if (di>=d) return 1;//不同的单位大于等于d
return 0;//小于d
}
int main()
{
scanf("%d%d%d",&n,&b,&d);//读入
h=-1;//初始化
for (int i=1;i<=n;i++)
{
yes=1;//初始化
while (yes)
{
yes=0; h++;//尝试下一个数
for (int j=1;j<=i-1;j++)//枚举前面的每一个编码
if (!ch(H[j],h))//符不符合
{
yes=1;//标记
break;//直接开始尝试下一个数(这一个数不是)
}
}
printf("%d ",h);//输出
H[i]=h;//记录
if (!(i%10))
printf("\n");//处理换行
}
return 0;
}