codeforces 1299A Anu Has a Function

传送门
codeforces 1299A Anu Has a Function_第1张图片
题意:给一个序列,让改变序列的顺序,使其经过一个运算,最后值最大。
分析:本题考就考这个运算,这个运算就是二进制,所以考的就是二进制。分析这个运算:(以下摘自tql tql tql tql)
/-------------------------------------------------------------------------------------------/
我们看这样一个操作他代表着什么?

我们把x,y拆解成二进制,x|y就相当于让两方都有1的一起有1了,然后−y就是让y位置上有1的减去。

举个例子,比如说x=1101,y=0111,那么就相当于说把x的最后一位1和第二位1带走了。

把所有数字拆成二进制,如果一个位置上的1,出现了多次(大于1),那么这个位置上的1肯定留不住。

所以我们就找最高位的出现一次的1,然后把它放到最前面去,之后的数字随便摆放。

可以模拟一下这个样例,9 5 9,把5摆到最前面上是最优解。
/---------------------------------------------------------------------------------------------/
也就是说,这个运算f(a,b)的结果是:将a,b转化为二进制,a为1,b为0的位是1,其他位是0。

代码:

#include
#include
#include
#include
#include
#include
#include
#include
#define sx(x)	scanf("%d",&x)
using namespace std;
	int a[100000+100];
	int num[50];
int main()
{
	int n;
	sx(n);
	memset(num,0,sizeof(num));
	int cnt=-1;
	for(int i=1;i<=n;i++)
	{
		sx(a[i]);
		int x=a[i];
		int tmp=0;
		while(x)						//将x转化成二进制,统计每个数每位1的数目
		{
			if(x&1)
				num[tmp++]+=1;
			else
				num[tmp++]+=0;
			x>>=1;
		}
		cnt=max(cnt,tmp);			//最大位数
	}
	int pos=-1;						//右移pos位
	for(int i=cnt-1;i>=0;i--)
	{
		if(num[i]==1)
		{
			pos=i;
			break;
		}
	}
	if(pos==-1){
		for(int i=1;i<=n;i++)
			printf("%d ",a[i]);
		cout<<endl;
		return 0;
	}
	for(int i=1;i<=n;i++){
		if(a[i]>>pos&1){
			swap(a[i],a[1]);
			break;
		}
	}
	for(int i=1;i<=n;i++){
		printf("%d ",a[i]);
	}
	cout<<endl;
	return 0;
}

补充,把一个数的二进制的各个位都求出来:

while(x)						//将x转化成二进制,统计每个数每位1的数目
		{
			if(x&1)						//and  最后一位与1进行and
				num[tmp++]=1;
			else
				num[tmp++]=0;
			x>>=1;						//右移
		}

你可能感兴趣的:(math,二进制)