Codeforces 768C:Jon Snow and his Favourite Number
题目链接:http://codeforces.com/contest/768/problem/C
题目大意:给定n个数,每次先排序后将奇数位上的数与x异或,求操作k次后的最大值和最小值。
循环节
打表观察操作10次数列的特点,可以发现每经过一定次数操作后,会变回原来的数列。
由此可以找到这个循环节解决这道题。
代码如下:
1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #include <cstring> 5 #define N 100005 6 using namespace std; 7 typedef long long ll; 8 int inf=1000000; 9 int n,k,x,a[N],l[50][N]; 10 int check(int x){ 11 for(int i=0;i<x;++i){ 12 bool f=1; 13 for(int j=0;j<n;++j){ 14 if(l[i][j]!=l[x][j]){ 15 f=0;break; 16 } 17 }if(f)return i; 18 } 19 return -1; 20 } 21 int main(void){ 22 cin>>n>>k>>x; 23 for(int i=0;i<n;++i){ 24 cin>>a[i]; 25 l[0][i]=a[i]; 26 } 27 int pre,time=1; 28 for(;time<=k;time++){ 29 sort(a,a+n); 30 for(int j=0;j<n;++j){ 31 if(j%2==0)a[j]^=x; 32 l[time][j]=a[j]; 33 } 34 pre=check(time); 35 if(pre!=-1)break; 36 } 37 if(k>time){ 38 int len=time-pre; 39 int finally=(k-time)%len; 40 time=pre+finally; 41 }else time=k; 42 int minn=inf,maxn=-inf; 43 for(int i=0;i<n;++i){ 44 minn=min(minn,l[time][i]); 45 maxn=max(maxn,l[time][i]); 46 } 47 cout<<maxn<<" "<<minn; 48 }