USACO 2.1 海明码(DFS)

Description

  给出 N,B 和 D:找出 N 个编码(1 <= N <= 64),每个编码有 B 位(1 <= B <= 8),使得两两编码之间至少有 D 个单位的“海明距离”(1 <= D <= 7)。“海明距离”是指对于两个编码,他们的二进制表示法中的不同二进制位的数目。看下面的两个编码 0x554 和 0x234 之间的区别(0x554 表示一个十六进制数,每个位上分别是 5,5,4):
    0x554 = 0101 0101 0100
    0x234 = 0010 0011 0100
  因为有五个位不同,所以“海明距离”是 5。

Input

一行,包括 N, B, D。

Output

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

题解

dfs;
Executing...
   Test 1: TEST OK [0.000 secs, 4180 KB]
   Test 2: TEST OK [0.000 secs, 4180 KB]
   Test 3: TEST OK [0.000 secs, 4180 KB]
   Test 4: TEST OK [0.000 secs, 4180 KB]
   Test 5: TEST OK [0.000 secs, 4180 KB]
   Test 6: TEST OK [0.000 secs, 4180 KB]
   Test 7: TEST OK [0.000 secs, 4180 KB]
   Test 8: TEST OK [0.000 secs, 4180 KB]
   Test 9: TEST OK [0.000 secs, 4180 KB]
   Test 10: TEST OK [0.000 secs, 4180 KB]
   Test 11: TEST OK [0.000 secs, 4180 KB]
All tests OK.

代码

/*
ID: zyx52yzl
LANG: C++
TASK: hamming
*/
#include <stdio.h>
#include <stdlib.h>
#include <iostream.h>
#define MAX (1 << 8 + 1)
#define NMAX 65
#define BMAX 10
#define DMAX 10

int nums[NMAX], dist[MAX][MAX];
int N, B, D, maxval;
FILE *in, *out;

void findgroups(int cur, int start) {
    int a, b, canuse;
    char ch;
    if (cur == N) {
        for (a = 0; a < cur; a++) {
            if (a % 10)
                fprintf(out, " ");
            fprintf(out, "%d", nums[a]);
            if (a % 10 == 9 || a == cur-1)
                fprintf(out, "\n");
        }
        exit(0);
    }
    for (a = start; a < maxval; a++) {
        canuse = 1;
        for (b = 0; b < cur; b++)
            if (dist[nums[b]][a] < D) {
                canuse = 0;
                break;
            }
        if (canuse) {
            nums[cur] = a;
            findgroups(cur+1, a+1);
        }
    }
}

int main() {
    in = fopen("hamming.in", "r");
    out = fopen("hamming.out", "w");
    int a, b, c;
    fscanf(in, "%d%d%d", &N, &B, &D);
    maxval = (1 << B);
    for (a = 0; a < maxval; a++)
        for (b = 0; b < maxval; b++) {
            dist[a][b] = 0;
            for (c = 0; c < B; c++) 
                if (((1 << c) & a) != ((1 << c) & b))
                    dist[a][b]++;
        }
    nums[0] = 0;
    findgroups(1, 1);
    return 0;
}
posted @ 2016-10-14 20:32  猪都哭了  阅读(369)  评论(0编辑  收藏  举报