Advertisement

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

复制代码

Sample Output

复制代码

上面的输出化为二进制数如下

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

全部评论 (0)

还没有任何评论哟~