题意是我复制别人的:题目大意就是给出1~n的置换序列, 然后给出一个整数k,和一个串问置换k次后的串是什么样子的。
首先,给出的串的长度是小于等于n的,不足的位置要补上空格。
然后置换k次,不是直接就循环着置换,因为置换内的每个循环都是有一定长度的,如果超过这个长度的置换次数,必然会和前面的某个状态一样,
所以对每个循环,如果长度为len,循环内的元素只需要置换k%len次即可。第一次看置换群得概念,不由得想起来之前的一道题,
就是给出一组无序的数,任意两个数之间可以互相交换位置,问最少要交换多少次达到升序状态,
那么这就显然是一个置换的问题了,只需要求出题目中循环的个数,用元素个数-循环个数即为所求了。
那么如果题目要求只能相邻的两个数之间进行交换,就是树状数组或者归并排序的问题了。
#include<iostream>
#include<string>
#include<nath>
using namespace std;int n; //给出的置换数
int key[201]; //存放对应的置换数
char str[201]; //要置换的字符串
char result[201]; //置换后的结果
int a[201]; int k;int len;
void init() { char c = getchar(); int i = 0; while(c != '\n') { str[i++] = c; c = getchar(); } for(;i < n;i++) str[i] = ' '; str[i] = '\0';
} void zhihuan() { int i; for(i = 0;i < n;i++) { int t = key[i]; int count = 1; while(t != i) { count++; t = key[t]; } a[i] = count; } } void solve() { int i,j; for(i = 0;i < n;i++) { int pos = i; for(j = 0;j < k%a[i];j++) { pos = key[pos]; } result[pos] = str[i]; // cout<<pos<<" ** "<<result[pos]<<endl; } result[n] = '\0'; } int main() { while(cin>>n && n) { for(int i = 0;i < n;i++) { cin>>key[i]; key[i]--; } while(cin>>k && k) { getchar(); init(); zhihuan(); solve(); cout<<result<<endl; } cout<<endl;
} return 0; }