题意:
有一个长度n的数列,琼恩有一个喜爱的数x,琼恩每次去隔一个 数对数列里的数异或,请问k次操作后数列里最大的数和最小的数分别是什么
解题思路:
这种题一般来说操作后的数列是有循环节的,然后看到群里qc爸爸问有没有循环节不是2的例子的时候就更确定了。先去模拟下操作,然后每次操作出来的数列都去和之前得到的数列比较,看看是否有相同的数列,如果有就找到循环节了,只要让k对应到这个循环节就可以求出答案
代码:
#include <bits/stdc++.h>using namespace std;const int maxn=1e5+5;int n, k, x;int a[maxn];int b[104][maxn];int c[maxn][3];int main(){ cin>>n>>k>>x; int i, j=0; c[j][0]=0;c[j][1]=maxn; for(i=0; i<n; i++) { scanf("%d", &a[i]); b[j][i]=a[i]; c[j][0]=b[j][i]>c[j][0]?b[j][i]:c[j][0]; c[j][1]=b[j][i]<c[j][1]?b[j][i]:c[j][1]; } sort(a, a+n);// for(i=0; i<n; i++)PRintf("%d ", a[i]);printf("/n"); j=1; bool sam=true; int s=0; while(1) { for(i=0; i<n; i++)b[j][i]=b[j-1][i]; sort(b[j], b[j]+n); for(i=0; i<n; i+=2){b[j][i]=b[j][i]^x;} sort(b[j], b[j]+n); sam=true; c[j][0]=0;c[j][1]=maxn; for(i=0; i<n; i++) { c[j][0]=b[j][i]>c[j][0]?b[j][i]:c[j][0]; c[j][1]=b[j][i]<c[j][1]?b[j][i]:c[j][1]; // printf("%d ", b[j][i]); } for(int e=1; e<j; e++) { sam=true; for(i=0; i<n; i++) { sam&=(b[j][i]==b[e][i]);// printf("%d %d %d/n", e, j, sam); } if(sam) { s=e; break; } } if(s)break;// cout<<j<<endl; j++;// if(j>=19)break;// if(j>10)break; } // printf("%d %d/n", s, j); if(k<s)printf("%d %d/n", c[k][0], c[k][1]); else { printf("%d %d/n",c[(k-s)%(j-s)+s][0], c[(k-s)%(j-s)+s][1]); } return 0;}
新闻热点
疑难解答