标签:循环节
题意:看着样例说吧 给你n个数字a[i](>0&&<=n),再给你交换次数k,之后是一串字符串;如果字符串长度小于n,后面补为空格;然后进行交换:之前字符串的位置i对应的 a[i]位置就是交换一次后的字符位置,问交换k次后的字符串;
分析:单纯模拟会超时,这其中有个规律:对于一个字符,交换某些次之后,就会变回原来的(即会循环),只需找出它的循环周期T,交换k%T次就可;
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <stdlib.h>
#define N 10010
#define INF 10000000
#define eps 10E-9
#define mem(a) memset(a,0,sizeof(a))
using namespace std;
int a[N];
int a_circle[N];
char str[N];
char stre[N];
char s[N];
int circle(int x)//找周期
{
int result=1,k=a[x];
while(1)
{
if(x==k)
return result;
k=a[k];
result++;
}
}
int main()
{
int n,k,i,j;
while(~scanf("%d",&n)&&n)
{
for(i=0; i<n; i++)
{
scanf("%d",&a[i]);
a[i]=a[i]-1;
}
while(~scanf("%d",&k)&&k)
{
getchar();
gets(str);
int len=strlen(str);
if(len<n)
{
for(i=len; i<n; i++)
str[i]=‘ ‘;
str[i]=‘\0‘;
}
for(i=0; i<n; i++)
{
a_circle[i]=circle(i);
}
char c;
for(i=0; i<n; i++)
{
int temp=k%a_circle[i];
int d=i;
// cout<<k<<endl;
while (temp--)//交换
d = a[d];
stre[d]=str[i];
}
for(i=0; i<n; i++)
printf("%c",stre[i]);
printf("\n");
}
printf("\n");
}
return 0;
}
标签:循环节
原文地址:http://blog.csdn.net/bigsungod/article/details/43227579