题目描述
给定一个整数 nn,表示 nn 张牌,牌的编号为 11 到 nn。
再给定一个洗牌置换 f1,f2,…,fnf1,f2,…,fn,进行一次洗牌操作时,应将第一号位置的牌交换到第 f1f1 号位置,将第 ii 号位置的牌交换到第 fifi 号位置。保证 ff 是一个 11 到 nn 的排列(即 11 到 nn 中的每个数字出现且只出现一次)。
一开始,牌的顺序为 1,2,⋯ ,n1,2,⋯,n。给定一个整数 kk,请输出经过 kk 次洗牌后牌的顺序。
输入格式
第一行:两个整数 nn 与 kk;
第二行:nn 个整数表示 f1,f2,…,fnf1,f2,…,fn。
输出格式
单独一行:nn 个整数表示洗 kk 次牌后的顺序。
数据范围
- 对于 30%30% 的数据,1≤n≤1001≤n≤100,1≤k≤10001≤k≤1000;
- 对于 60%60% 的数据,1≤n≤10001≤n≤1000,1≤k≤10,0001≤k≤10,000;
- 对于 100%100% 的数据,1≤n≤100,0001≤n≤100,000,1≤k≤1,000,000,0001≤k≤1,000,000,000。
样例数据
输入:
4 2
4 1 2 3
输出:
3 4 1 2
说明:
1234-->2341-->3412
输入:
3 100000
1 2 3
输出:
1 2 3
说明:
每次洗牌都不会改变牌的位置
详见代码:
#include <bits/stdc++.h>
using namespace std;
int n,k;
int f[100005];
int a[100005];
int main()
{scanf("%d%d",&n,&k);for(int i=1;i<=n;i++){scanf("%d",&f[i]);}for(int i=1;i<=n;i++){if (a[i]==0){vector<int> v;v.push_back(f[i]);while (v[0]!=f[v.back()]){v.push_back(f[v.back()]);}int m=v.size();int d=k%m;for(int j=0;j<v.size();j++){a[v[(j+d)%m]]=v[j];}}}for(int i=1;i<=n;i++){cout<<a[i]<<" ";}return 0;
}