http://ace.delos.com/usacoprob2?a=4g9XJlxo9kU&S=hamming
懂异或的人都会这题。水题,不过要了解好题意,这里的两两编码之间的距离指的不是一定要在邻近位置,应该是所有数都应该成立的一条规定。
比如样例:
0 7 25 30 42 45 51 52 75 76
82 85 97 102 120 127
25与其他所有数都应该满足海明距离,而不仅仅是与7和30的海明距离。
#include <iostream> #include <string.h> #include <cstdio> using namespace std; const int B[9]={0,1,3,7,15,31,63,127,255}; int f[200]={0}; int n,b,d; bool check(int x) { int dd=0; while (x>0) { if (x%2==1) dd++; x/=2; } if (dd>=d) return true; else return false; } int main() { freopen("hamming.in","r",stdin); freopen("hamming.out","w",stdout); cin>>n>>b>>d; int sum=1; f[1]=0; bool flag; for (int i=1;i<=B[b] && sum<n;i++) { flag=true; for (int j=1;j<=sum;j++) if (!check(i^f[j])) { flag=false; break; } if (flag) f[++sum]=i; } for (int i=1;i<sum;i++) { if (i%10==0) cout<<f[i]<<endl; else cout<<f[i]<<" "; } cout<<f[sum]<<endl; return 0; }
网上找到的一个快速判断二进制数1的个数的方法:
int count(int n) { int ret = 0; while(n) { n = n&(n-1); ret++; } return ret; }
出处:http://blog.csdn.net/mcg890414/article/details/5870044
简单的证明:
先从简单说起。
假设a=00010000
这样才能把a用n(n代表1的个数)次变换变成0?若要按“与”操作,则00001111可以完成任务,同样,00000111,00000011,00000001也可以,但是只有00001111与a有最直接的关系,因为00001111=00010000-1.
当1的个数增多时,上面的方法同样适用,具体的样例链接上有了。