Luogu P5550 Chino的数列 题解

Luogu P5550 Chino的数列 题解

这Chino不会是那个チノ吧?

基本思路

找规律(

事实上,我们来手动模拟一下这道题,我们会发现一些有趣的事实

假设 a[i] 为题目给出的数列,s=3,m=5

k a[1] a[2] a[3] a[4] a[5] a[6] a[7]
0 1 2 3 4 5 6 7
1 2 5 4 3 6 7 1
2 5 6 3 4 7 1 2
3 6 7 4 3 1 2 5
4 7 1 3 4 2 5 6

(下略)

发现什么没?

数字 3,4 只出现在 a[3],a[4]

如果我们再仔细观察就会发现,事实上如果将原数列的第 s1m 的数去除,所剩的数组成的数列正好满足平移关系

而将原数列的第 s1m 的数组成一个新的数列,也满足平移关系

所以实际上这道题就是两个数列的平移关系,只需要知道平移 k 次后各个数据所在的位置即可

代码实现

#include<bits/stdc++.h>
using namespace std;
#define GO(u,v,i) for(register int i=u;i<=v;i++)
#define swp(a,b) a^=b,b^=a,a^=b
//可自行验证,这个算法可以快速交换两个变量的值

//快读
template<class t>inline t fr(){
    register t num=0,dis=1;
    register char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')dis=-1;ch=getchar();}
    while(ch<='9'&&ch>='0'){num=(num<<1)+(num<<3)+(ch^48);ch=getchar();}
    return num*dis;
}

//快写
template<class t>inline void fw(t num){
    if(num>9)fw(num/10);
    putchar(num%10+'0');
}
template<class t>inline void fw(t num,char ch){
    if(num<0)num=-num,putchar('-');
    fw(num);putchar(ch);
}
typedef long long lld;
//题目数据
const int maxn=100;
int n,s,m;
lld k;
int ou,in;//用于记录两个数列的长度
lld numout[maxn],numin[maxn];//两个数列
signed main(){
    n=fr<int>();s=fr<int>();m=fr<int>();k=fr<lld>();;
    if(s>m)swp(s,m);//保证s<=m
    GO(1,s-1,i)numout[++ou]=fr<lld>();
    GO(s,m-1,i)numin[++in]=fr<lld>();
    GO(m,n,i)numout[++ou]=fr<lld>();
    numout[0]=numout[ou];
    numin[0]=numin[in];
    GO(1,s-1,i)fw(numout[(i+k)%ou],' ');
    GO(1,in,i)fw(numin[(i+k)%in],' ');
    GO(s,n-m+s,i)fw(numout[(i+k)%ou],' ');//快速确定位置
    return 0;
}
//============Copyright(C)2022,Locked_Fog.===============
posted @   Locked_Fog  阅读(70)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示
主题色彩