poj 1721 CARDS (置换群)
题意:给你一个数列,第i号位置的数位a[i],现在将数列进行交换,交换规则为a[i]=a[a[i]];已知交换s次之后的序列,求原先序列
思路:置换的问题必然存在一个循环节,使一个数列交换n次回到原来的数列上,我们只需要模拟交换找到循环节长度len,将已知的交换后的序列,则再进行 (len - s%len) 次交换即可得到原序列
代码:
#include <cstdio> #include <cstring> #include <iostream> #define maxn 1000 using namespace std; int main(int argc, char const *argv[]) { int data[maxn]; int a[maxn],b[maxn],c[maxn]; int n,s; while(cin>>n>>s) { for(int i=1;i<=n;i++) { cin>>data[i]; a[i]=b[i]=c[i]=data[i]; } int len = 0; int o=3; while(1) { for(int i=1;i<=n;i++) a[i]=b[a[i]]; for(int i=1;i<=n;i++) b[i]=a[i]; int k=1; len++; for(int i=1;i<=n;i++) if(a[i]==data[i]) k++; if(k==n+1) break; } len = len - s%len; for(int j=1;j<=len;j++) { for(int i=1;i<=n;i++) data[i]=c[data[i]]; for(int i=1;i<=n;i++) c[i]=data[i]; } for(int i=1;i<=n;i++) cout<<data[i]<<endl; } return 0; }