codeforces 768 C Jon Snow and his Favourite Number(循环节)

来源:互联网 发布:java线程之间的通信 编辑:程序博客网 时间:2024/06/05 15:48

题意:

有一个长度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;}


0 0
原创粉丝点击