标签:置换群
http://poj.org/problem?id=1026
大致题意:给出数字n和一个1~n的序列num[]。然后给出若干个字符串,让字符串的下标i和num[i]交换,问交换K次后得到的字符串是什么。输入的字符串长度小于等于n,若小于n就用空格来补。
例如样例1
4 5 3 7 2 8 1 6 10 9H e L L o B o b ‘ ‘ ‘ ‘
那么得到str[4] = ‘H’,str[5] = ‘e‘, str[3] = ‘L‘.....
思路: 对于置换
4 5 3 7 2 8 1 6 10 9 = (1 7 4)(2 5)(3)(6 8)(9 10)
1 2 3 4 5 6 7 8 9 10
所以只需求出每个轮换的循环节t,对于原来第i个字符只需循环 k%t次后就能得到它的目标位置。
#include <stdio.h> #include <iostream> #include <algorithm> #include <set> #include <map> #include <vector> #include <math.h> #include <string.h> #include <queue> #include <string> #include <stdlib.h> #define LL long long #define _LL __int64 #define eps 1e-8 using namespace std; const int INF = 0x3f3f3f3f; const int maxn = 10; int n,k; char s[210]; int a[210]; int ans[210]; //保存第i个字符所在轮换的循环节 char str[210]; void solve() { int i; for(i = 1; i <= n; i++) { int cnt = 1; int t = a[i]; while(t != i) { cnt++; t = a[t]; } ans[i] = cnt; } } int main() { while(~scanf("%d",&n) && n) { int i; for(i = 1; i <= n; i++) scanf("%d",&a[i]); solve(); while(~scanf("%d",&k) && k) { getchar(); gets(s+1); int len = strlen(s+1); for(i = len+1; i <= n; i++) s[i] = ' '; s[n+1] = '\0'; for(i = 1; i <= n; i++) { int t = i; for(int j = 0; j < k%ans[i]; j++) t = a[t]; str[t] = s[i]; } str[n+1] = '\0'; cout << str+1 << endl; } cout << endl; } return 0; }
poj 1026 Cipher(置换),布布扣,bubuko.com
标签:置换群
原文地址:http://blog.csdn.net/u013081425/article/details/29558141