1. 程式人生 > >USACO2.1.5 Hamming Codes 海明碼 解題報告(列舉)

USACO2.1.5 Hamming Codes 海明碼 解題報告(列舉)

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 不同的二進位制位: xxx xx 因為有五個位不同,所以“海明距離”是 5。

Input

一行,包括 N, B, D。

Output

N 個編碼(用十進位制表示),要排序,十個一行。如果有多解,你的程式要輸出這樣的解:假如把它化為 2^B 進位制的數,它的值要最小。

Sample Input

16 7 3

Sample Output

0 7 25 30 42 45 51 52 75 76
82 85 97 102 120 127

上面的輸出化為二進位制數如下

0000000 0000111 0011001 0011110 0101010 0101101 0110011 0110100 1001011 1001100 1010010 1010101 1100001 1100110 1111000 1111111

讓你找出N個數,這N個數最大為2^B,且每個數之間都至少有D位不同

從0-2^B列舉即可,將i和前面存下的所有答案對比,滿足條件就存進去,這裡我們判不同位的個數可以直接用異或(相同為0不同為1),然後用函式求出異或後'1'的個數即可

程式碼如下

#include <map>
#include <queue>
#include <cmath>
#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
#define lowbit(a) (a&(-a))
#define _mid(a,b) ((a+b)/2)
#define _mem(a,b) memset(a,0,(b+3)<<2)
#define fori(a) for(int i=0;i<a;i++)
#define forj(a) for(int j=0;j<a;j++)
#define ifor(a) for(int i=1;i<=a;i++)
#define jfor(a) for(int j=1;j<=a;j++)
#define mem(a,b) memset(a,b,sizeof(a))
#define IN freopen("in.txt","r",stdin)
#define OUT freopen("out.txt","w",stdout)
#define IO do{\
    ios::sync_with_stdio(false);\
    cin.tie(0);\
    cout.tie(0);}while(0)
using namespace std;
typedef long long ll;
const int maxn =  150+10;
const int INF = 0x3f3f3f3f;
const int inf = 0x3f;
const double EPS = 1e-7;
const double Pi = acos(-1);
const int MOD = 1e9+7;
int Minbit;
int a[maxn];
int cnt;
bool juge(int x){
    fori(cnt)
        if(__builtin_popcount(x^a[i])<Minbit)    //編譯器內建函式,求出x^a[i]的二進位制數中'1'的個數
            return false;
    return true;
}
int main(){
    int n,b;
    cin >> n >>b >>Minbit;
    fori(1<<b){
        if(juge(i))
            a[cnt++] = i;
        if(cnt == n)
            break;
    }
    int cn = 1;
    fori(cnt){
        cout <<a[i];
        if(cn%10==0)
            cout << endl;
        else if(i!=cnt-1)
            cout <<" ";
        cn++;
    }
    return 0;
}