codeforces 1299A Anu Has a Function

传送门
在这里插入图片描述
题意:给一个序列,让改变序列的顺序,使其经过一个运算,最后值最大。
分析:本题考就考这个运算,这个运算就是二进制,所以考的就是二进制。分析这个运算:(以下摘自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<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<queue>
#include<deque>
#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;						//右移
		}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值