洛谷P1461 海明码 Hamming Codes

P1461 海明码 Hamming Codes

  •  
  • 98通过
  • 120提交
  • 题目提供者该用户不存在
  • 标签USACO
  • 难度普及/提高-

 提交  讨论  题解  

最新讨论

  • 暂时没有讨论

题目描述

给出 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。

输入输出格式

输入格式:

一行,包括 N, B, D。

输出格式:

N 个编码(用十进制表示),要排序,十个一行。如果有多解,你的程序要输出这样的解:假如把它化为2^B进制数,它的值要最小。

输入输出样例

输入样例#1

16 7 3

输出样例#1

0 7 25 30 42 45 51 52 75 76

82 85 97 102 120 127

说明

必须与其他所有的数相比,Hamming距离都符合要求,这个数才正确 什么意思啊??? 答:如样例输出,0和7,0和25,0和……比较都符合海明码,同样7和25,7和30,7和……比较也符合要求,以此类推。 就这样了。 题中至少有D个单位,意思就是大于等于D个单位的都可以。

USACO 2.1

翻译来自NOCOW

分析:这个题目有点奇怪,告诉的B其实没多大用,因为没有B位可以通过添加0来补,也就是告诉了你一个范围,那么好办,要求字典序最小,我先把8位二进制数的最大数算出来,然后一一添加数进去看能不能满足要求,然后输出前n个即可.

想到二进制可以用二进制运算,^可以快速算出两个二进制数不同的位数.

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

int n, b, d, ans[260], num = 1;

bool check(int x, int N, int tempd)
{
    for (int i = 1; i <= N; i++)
    {
        int temp = x ^ ans[i],cnt = 0;
        while (temp)
        {
            if (temp % 2 == 1)
                cnt++;
            temp /= 2;
        }
        if (cnt < tempd)
            return false;
    }
    return true;
}

int main()
{
    scanf("%d%d%d", &n, &b, &d);
    ans[1] = 0;
    for (int i = 1; i <= 256; i++)
        if (check(i, num, d))
            ans[++num] = i;
    for (int i = 1; i <= n; i++)
    {
        printf("%d", ans[i]);
        if (i % 10 == 0 || i == n)
            printf("\n");
        else
            if (i < n)
                printf(" ");
    }
    while (1);

    return 0;
}

 

posted @ 2016-09-26 21:51  zbtrs  阅读(419)  评论(0编辑  收藏  举报