zoukankan      html  css  js  c++  java
  • USACO Hamming Codes DFS 构造

    我还是用了很朴素的暴力匹配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, "
    ");
            }
            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个数之后输出一下就可以了

  • 相关阅读:
    hdu 5366 简单递推
    hdu 5365 判断正方形
    hdu 3635 并查集
    hdu 4497 数论
    hdu5419 Victor and Toys
    hdu5426 Rikka with Game
    poj2074 Line of Sight
    hdu5425 Rikka with Tree II
    hdu5424 Rikka with Graph II
    poj1009 Edge Detection
  • 原文地址:https://www.cnblogs.com/wushuaiyi/p/4291978.html
Copyright © 2011-2022 走看看