题意:给定一个长度 为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);
}
}

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

被折叠的 条评论
为什么被折叠?



