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)
还没有任何评论哟~
