码迷,mamicode.com
首页 > 其他好文 > 详细

USACO Hamming Codes DFS 构造

时间:2015-02-14 17:23:18      阅读:194      评论:0      收藏:0      [点我收藏+]

标签:

我还是用了很朴素的暴力匹配A了这题,不得不感叹USACO时间放的好宽...

技术分享
/*
ID: wushuai2
PROG: hamming
LANG: C++
*/
//#pragma comment(linker, "/STACK:16777216") //for c++ Compiler
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <cstring>
#include <cmath>
#include <stack>
#include <string>
#include <map>
#include <set>
#include <list>
#include <queue>
#include <vector>
#include <algorithm>
#define Max(a,b) (((a) > (b)) ? (a) : (b))
#define Min(a,b) (((a) < (b)) ? (a) : (b))
#define Abs(x) (((x) > 0) ? (x) : (-(x)))
#define MOD 1000000007
#define pi acos(-1.0)

using namespace std;

typedef long long           ll      ;
typedef unsigned long long  ull     ;
typedef unsigned int        uint    ;
typedef unsigned char       uchar   ;

template<class T> inline void checkmin(T &a,T b){if(a>b) a=b;}
template<class T> inline void checkmax(T &a,T b){if(a<b) a=b;}

const double eps = 1e-7      ;
const int M = 660000         ;
const ll P = 10000000097ll   ;
const int INF = 0x3f3f3f3f   ;
const int MAX_N = 20         ;
const int MAXSIZE = 101000000;

int n, b, d;
int ans[80];

bool func(int b){
    int i, j, cnt;
    int t1[50], t2[50];
    memset(t2, 0, sizeof(t2));
    while(b){
        t2[++t2[0]] = b % 2;
        b = (b - b % 2) / 2;
    }
    for(int k = 1; k <= ans[0]; ++k){
        cnt = 0;
        int a = ans[k];
        memset(t1, 0, sizeof(t1));
        while(a){
            t1[++t1[0]] = a % 2;
            a = (a - a % 2) / 2;
        }
        for(i = 1; i <= Max(t1[0], t2[0]); ++i){
            if(t1[i] != t2[i])  ++cnt;
        }
        if(cnt < d)    return false;
    }
    return true;
}

int main() {
    ofstream fout ("hamming.out");
    ifstream fin ("hamming.in");
    int i, j, k, t, n, s, c, w, q;
    fin >> n >> b >> d;
    ++ans[0];
    ans[1] = 0;
    int num = 1;
    while(ans[0] <= n){
        if(func(num)){
            ++ans[0];
            ans[ans[0]] = num;
        }
        ++num;
    }
    for(i = 1; i < ans[0]; ++i){
        fout << ans[i];
        if(i == ans[0] - 1){
            break;
        }
        if(i % 10 == 0) fout << endl;
        else    fout <<  ;
    }
    fout << endl;

    fin.close();
    fout.close();
    return 0;
}
View Code

不过看了官方题解觉得很不错,来分享一下

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]++;
        }

通过以上这段代码可以找到所有1 << B 中所有数的关系,就是二进制下不同的位数

然后通过一个DFS 来找可行对

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);
        }
    }
}

不难得出,核心代码很短也很好写

找到全部N个数之后输出一下就可以了

USACO Hamming Codes DFS 构造

标签:

原文地址:http://www.cnblogs.com/wushuaiyi/p/4291978.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!