您的位置:首页 > 其它

poj1026 模拟

2016-03-08 15:27 204 查看
题意:首先输入一个大小为n的整数数组,该数组元素彼此不重复,个人称之为变换数组(因数组从0开始,为了与数组进行对应,请将实际数值减一)。 

然后输入一个整数k和一个字符串,k为变换的次数,字符串的长度如果小于变换数组的长度n,用空格补齐。现求经过k次变换后的字符串的结果。

样例说明:

10

4 5 3 7 2 8 1 6 10 9

1 Hello Bob

变换数组:

4 5 3 7 2 8 1 6 10 9

减一后的变换数组:

3 4 2 6 1 7 0 5 9 8

变换数组的含义:

字符串的第0个元素变换到第3个位置

字符串的第1个元素变换到第4个位置

....依次类推

所以,经过1次变换后,字符串Hello Bob的输出结果为:BolHeol  b

算法:模拟。但是对于变换次数k,不能直接模拟,否则会超时。经分析可以发现,对于第0个元素,1次变换后到达第3个位置,2次变换后到达第6个位置,

3次变换后到达第0个位置,即回到最初的位置。因此,第0个元素的循环周期为3。因此,对每个元素求得其循环周期,用k取模之,便是实际要模拟变换的次数。
注:请自行查阅置换群。

#include <iostream>
#include <string.h>
using namespace std;

int main()
{
int n;
int a[210];				// 变换数组
int cycle[210];			// 循环周期
char c[210];			// 输入的字符串
char ans[210];			// 输出结果
int k;					// 变换次数
while (cin >> n && n > 0)
{
// 输入变换数组
for (int i=0; i<n; i++)
{
cin >> a[i];
a[i]--;
}
// 求循环数组
for (int i=0; i<n; i++)
{
int cnt = 0;
int key = i;
while (a[key] != i)
{
cnt++;
key = a[key];
}
cycle[i] = cnt + 1;
}
while (cin >> k && k > 0)
{
getchar();
gets(c);
int len = strlen(c);
// 如果字符串长度小于n,用空格补齐
if (len < n)
{
for (int i=len; i<n; i++)
{
c[i] = ' ';
}
c
= '\0';
}
// 对每一个字符
for (int i=0; i<n; i++)
{
int tmpi = i;
int times = k % cycle[i];			// 对字符c[i]进行times次变换
int t = i;							// 字符c[i]最终所在的位置为t (初始化为i是因为该字符变换的位置可能是它当前的位置!!!)
for (int j=0; j<times; j++)
{
t = a[tmpi];
tmpi = t;
}
ans[t] = c[i];
}
ans
= '\0';
cout << ans << endl;
}
cout << endl;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  poj 模拟