[USACO2.1]海明码 Hamming Codes

题目

题目大意

给出出0~2B的数

要求找出N个数,使得两两数在二进制之间至少有 D 个位不相同

题目解析

枚举每个数是否和当前的数列发生冲突,不冲突则入数列,且数列第一个一定是0

至于判断两个数是否冲突,这里并不一定是最好的方法,提供一种方法

利用 x&(-x) 求出数中哪几位为1

循环比较有多少位不同,判断是否有冲突

代码

#include<bits/stdc++.h>
using namespace std;
int n,b,d,a[300],ai;
int qw(int x)
{
	return x&(-x);
}
bool check(int x)
{
	int l,r,k,li,ri;
	for(int i=0;i<=ai;i++)
	{
	  l=a[i];r=x;k=0;
	  bool flag[2][300];
	  memset(flag,0,sizeof(flag));
	  while(l>0)
	  {
	  	li=qw(l);
	  	l-=li;
	  	flag[0][li]=1;
	  }//求l的哪些位为1 
	  while(r>0)
	  {
	  	ri=qw(r);
	  	r-=ri;
	  	flag[1][ri]=1;
	  }//求r的哪些位为1 
	  for(int i=1;i<(1<<b);i++)
	   if(flag[0][i]!=flag[1][i])//判断是否有冲突 
	    k++;
	  if(k<d)
	   return false;
	}
	return true;
}
int main()
{
	cin>>n>>b>>d;
	for(int i=1;i<(1<<b);i++)//一一枚举,1~2^b  
	{
	  if(check(i))
	   a[++ai]=i;
	}
	for(int i=0;i<n;i++)
	{
	  if(i%10==0&&i!=0)//每行10个 
	   cout<<endl;
	  cout<<a[i]<<" ";
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值