题目链接:https://www.luogu.org/problemnew/show/T2078
题目背景
HKE带着nn个小朋友做游戏
题目描述
现在有n个座位编号为11至nn,这些小朋友也编号11至nn。一开始所有小朋友都坐在相应的座位上。HKE的游戏可用一个n的排列A(A_1,A_2\cdots _nA(A 1 ,A 2 ⋯A n )表示。一轮游戏时,对于所有的1\leq i\leq n1≤i≤n,坐在位置ii上的小朋友坐到位置A_iA i 上。
现在游戏进行了kk轮,HKE想知道游戏结束后,位置1,2\cdots n1,2⋯n分别坐了几号小朋友?
输入输出格式
输入格式:
第一行n,kn,k。
第二行A_1,A_2\cdots A_nA 1 ,A 2 ⋯A n
输出格式:
一行n个数表示位置1,2……n1,2……n上的小朋友的编号
输入输出样例
输入样例#1: 复制
5 5
2 3 1 5 4
输出样例#1: 复制
2 3 1 5 4
输入样例#2: 复制
5 4
2 3 1 5 4
输出样例#2: 复制
3 1 2 4 5
说明
30%的数据,n\leq1000n≤1000,k\leq1000k≤1000
100%的数据,n\leq100000n≤100000,k\leq2^{31}-1k≤2
31
−1
一开始打了个30分代码如下:
#include<iostream>
#include <algorithm>
using namespace std;
int k,n,a[100010],b[100010],c[100010];
int main()
{
cin>>n>>k;
for (int i=1;i<=n;i++)
{
cin>>a[i];
b[i]=i;
}
for (int i=1;i<=k;i++)
{
for (int j=1;j<=n;j++)
{
c[a[j]]=b[j];
}
for (int j=1;j<=n;j++)
{
b[j]=c[j];
cout<<b[j]<<" ";
}
cout<<endl;
}
// for (int j=1;j<=n;j++)
// {
// cout<<b[j]<<" ";
// }
return 0;
}
大神给了个AC代码如下,仰望大神啊。
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
int A[100001];
int s[100001],t[100001];
long long n,k;
long long m,p,q,r;
cin >> n >> k;
for(long long i=1;i<=n;i++){
cin >> A[i];
s[i]=0;
}
for(long long i=1;i<=n;i++){
if(s[i]>0) continue;
m=0;
p=i;
t[0]=i;
do{//计算单个数重复周期
p=A[p];
m++;
t[m]=p;
}while(p!=i);
q=k%m;
p=i;
do{//全环设置
r=t[q];
s[r]=p;
p=A[p];
q++;
q=q%m;
}while(p!=i);
}
for(long long i=1;i<=n;i++){
cout << s[i] << " ";
}
return 0;
}