• 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个数之后输出一下就可以了

  • 相关阅读:
    前端:js
    HTML和CSS总结
    前端二:CSS
    前端一:走进HTML
    SQLALchemy(连表)、paramiko
    上下文管理、线程池、redis订阅和发布
    P4234 最小差值生成树
    P2387 [NOI2014]魔法森林
    P3721 [AH2017/HNOI2017]单旋
    P4271 [USACO18FEB]New Barns
  • 原文地址:https://www.cnblogs.com/wushuaiyi/p/4291978.html
Copyright © 2020-2023  润新知