poj1026 模拟

题意:首先输入一个大小为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[n] = '\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[n] = '\0';
			cout << ans << endl;
		}
		cout << endl;
	}
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kangwq2017

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值