題目描述
給定一個整數?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;
}