[USACO2.1]海明码 Hamming Codes

版权声明:虽然本蒟蒻很菜,但各位dalao转载请注明出处谢谢。 https://blog.csdn.net/xuxiayang/article/details/84670596

链接

洛谷
USACO


大意

求一个长度为 n n 的且后面的数与前面的数的亦或值中1的个数必须要不小于 d d 序列,如果有多组解输出最小的那个

数据范围: n 64 , 2 8 , d 7 n\leq 64,每个数\leq 2^8,d\leq 7


思路

其实大意是理解过后改变的,我们发现理解题目后这就变成了一道位运算的 s b sb 题,用 l o w b i t lowbit 操作或者暴力都可以


代码

/*
ID:hzbismy1
LANG:C++
TASK:hamming
*/
#define file(x) freopen(#x".in","r",stdin);freopen(#x".out","w",stdout)
#include<cstdio>
#include<cctype>
using namespace std;int n,m,d,ans[65],len,i;
bool ok;
inline char Getchar()
{
    static char buf[100000],*p1=buf+100000,*pend=buf+100000;
    if(p1==pend)
	{
        p1=buf; pend=buf+fread(buf,1,100000,stdin);
        if (pend==p1) return -1;
    }
    return *p1++;
}
inline int read()
{
	char c;int d=1,f=0;
	while(c=Getchar(),!isdigit(c))if(c==45)d=-1;f=(f<<3)+(f<<1)+c-48;
	while(c=Getchar(),isdigit(c)) f=(f<<3)+(f<<1)+c-48;
	return d*f;
}
inline void write(register long long x)
{
	if(x<0)write(45),x=-x;
	if(x>9)write(x/10);
	putchar(x%10+48);
	return;
}
inline int getk(register int x)
{
	int ans=0;
	while((x&-x)!=0)
	{
		ans++;
		x-=x&-x;
	}
	return ans;
}
signed main()
{
	file(hamming);
	n=read();m=read();d=read();//其实m就是限制序列中每个数的大小,不过数据很水保证有解,所以我忽略了
	ans[++len]=0;//初始化
	for(;len<n;i++)//这里条件其实还要加上i<(1<<m),但数据水所以不需要
	{
		ok=true;
		for(register int j=1;j<=len;j++) if(getk(ans[j]^i)<d) {ok=false;break;}//判断i是否满足条件
		if(ok) ans[++len]=i;//满足条件放入i
	}
	putchar(48);for(register int i=2;i<=len;i++) {if(i%10!=1) putchar(32);write(ans[i]);if(i%10==0)putchar(10);}
	if(len%10)putchar(10);//USACO恶心的卡格式
}

猜你喜欢

转载自blog.csdn.net/xuxiayang/article/details/84670596