CodeForces 768C Jon Snow and his Favourite Number 暴力 空间换时间

本文介绍了一种通过排序和异或操作来求解数组最大值和最小值的方法。具体步骤包括:1. 将数组按升序排列;2. 对奇数位置的元素执行异或操作。通过迭代该过程k次,最终得出所需的最大值和最小值。

题意:给定一个长度 为n个数得数组a,一个数字x,一个数字k;现在对数组进行以下步骤,1.将数字从小到大排序,2.将奇数位置的数与x异或,偶数位置不变。会得到一个新的数组。一个这样的两个步骤称为操作,求进行k次后,最大值和最小值。

思路:点击打开链接 这样的做法长姿势了

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int INF = 1<<30;
const int maxn = 1090;
int num[2][maxn];
int main()
{
	int n,x,k;
	//freopen("in.txt","r",stdin);
	while(scanf("%d%d%d",&n,&k,&x)!=EOF)
	{
		int buf,ma,mi;
		ma=-INF;mi=INF;
		for(int i=0;i<n;i++)
		{
			scanf("%d",&buf);
			num[0][buf]++;
			if(ma<buf)ma=buf;
			if(mi>buf)mi=buf;
		}
		for(int i=0;i<k;i++)
		{
			int now=1;//正在判断now个数  用来确定奇偶 
			memset(num[(i+1)&1],0,sizeof(num[(i+1)&1]));
			for(int j=mi;j<=ma;j++)
			{
				if(num[i&1][j]==0)continue;
				int a = j^x;
				if((num[i&1][j]&1)==0)//j有偶数个 
				{
					num[(i+1)&1][a]+=num[i&1][j]/2;//异或后a有一半放到奇数位置上,一半一要异或,一半不要异或 
					num[(i+1)&1][j]+=num[i&1][j]/2;
				}
				else if(now&1)//j处在奇数位置上  
				{
					num[(i+1)&1][a]+=(num[i&1][j]/2)+1;//now位置处变为a , 剩下的又是偶数个 ,所以a多一个 
					num[(i+1)&1][j]+=num[i&1][j]/2;
				}
				else //j处在第偶数个位置上 
				{
					num[(i+1)&1][a]+=num[i&1][j]/2;
					num[(i+1)&1][j]+=(num[i&1][j]/2)+1;//j 要多一个,少一个异或的 
				}
				now+=num[i&1][j];
			}
			ma=-INF;mi=INF;
			for(int kk=0;kk<maxn;kk++)
			{
				if(num[(i+1)&1][kk])
				{
					if(ma<kk)ma=kk;
					if(mi>kk)mi=kk;
				}
			}
		}
		printf("%d %d\n",ma,mi);
	}
} 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值