1. 程式人生 > >codeforces 768 C Jon Snow and his Favourite Number(迴圈節)

codeforces 768 C Jon Snow and his Favourite Number(迴圈節)

題意:

有一個長度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;
}