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

106 篇文章 0 订阅
51 篇文章 0 订阅

题意:

有一个长度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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值