POJ 1026 Cipher 题解

看似简单的字符串处理,不过直接暴力法是会超时的。

故此需要优化,这里使用周期优化。

研究过数列序列的都知道,其实序列反复调用另外一个序列得到一个新的序列,都会出现周期的,问题是周期何时出现,如果利用这个周期。

这就需要分开每个数,使用一个新的数列记录每个数的周期,利用这个周期截去一大段数据,那么剩下的数据就很好处理了。

因为所有的周期数总和都不会超过n,数列的长度的,所以时间效率可以达到O(n),常数项为2.

其他难度,我觉得相对新手来说,就是执行的细节最困难了,比如下标的准确性,如何移动数据等,考个人的编程功底了。

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

int keys[201];
int keysCycle[201];
char str[205];
char res[205];
int n, repeat;

void getCycle()//原始暴力法超时,需要利用周期优化
{
	memset(keysCycle, 0, sizeof(int)*(n+1));
	for (int i = 1; i <= n; i++)
	{
		if (!keysCycle[i])
		{
			int c = 1, j = i;
			while (keys[j] != i)
			{
				j = keys[j];
				c++;
			}
			j = i;
			keysCycle[j] = c;
			while (keys[j] != i)
			{
				j = keys[j];
				keysCycle[j] = c;
			}
		}
	}
}

int main()
{
	while (scanf("%d", &n) && n)
	{
		for (int i = 1; i <= n; i++)
		{
			scanf("%d", &keys[i]);
		}
		getCycle();

		while (scanf("%d", &repeat) && repeat)
		{
			gets(str);	//We don't use the first 0 index
			int len = strlen(str);
			while (len <= n)
			{
				str[len++] = ' ';
			}//patch the ending with ' ' while len <= n
			str[len] = '\0';	//put back the '\0' ending character

			for (int i = 1; i <= n; i++)
			{
				int rep = repeat % keysCycle[i];
				int j = i;
				while (rep--) j = keys[j];
				res[j] = str[i];
			}
			for (int i = 1; i <= n; i++)
			{
				putchar(res[i]);
			}
			putchar('\n');
		}
		putchar('\n');
	}
	return 0;
}

POJ 1026 Cipher 题解

时间: 2024-11-06 16:58:23

POJ 1026 Cipher 题解的相关文章

[ACM] POJ 1026 Cipher (组合数学,置换)

Cipher Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 19228   Accepted: 5148 Description Bob and Alice started to use a brand-new encoding scheme. Surprisingly it is not a Public Key Cryptosystem, but their encoding and decoding is base

poj 1026 Cipher

http://poj.org/problem?id=1026 这道题题意是给你一个置换群,再给你一个字符串,输出经过k次置换的字符串. 就是找循环节. 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define maxn 3000 5 using namespace std; 6 7 int a[maxn],key[maxn]; 8 int n,k; 9 char str[maxn]

poj 1026 Cipher (置换群)

链接:poj 1026 题意:给定n个大小1-n的不同的整数作为密钥,给定一个字符串, 求将该字符串经过k次编码后的字符串 分析:暴力求解会超时,可以利用置换群的知识解题 置换群:一个有限集合的一一变换叫做置换,一对对置换组成了置换群. 对于一个集合a(a[1],a[2],a[3]...a[n]) 通过置换可以变成 (b[a[1]],b[a[2]],b[a[3]]...b[a[n]]) b的作用就是置换(可以理解为某种函数的作用),将原来的集合映射成具有 相应次序的集合a',a'可以看做是a的相

POJ 1026 Cipher[置换]

Cipher 时限:1000MS Description Bob and Alice started to use a brand-new encoding scheme. Surprisingly it is not a Public Key Cryptosystem, but their encoding and decoding is based on secret keys. They chose the secret key at their last meeting in Phila

POJ 1026 Cipher(置换)

                                                               Cipher Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 19502   Accepted: 5239 Description Bob and Alice started to use a brand-new encoding scheme. Surprisingly it is not a P

POJ 1026 Cipher(置换群)

题目链接 题意 :由n个数字组成的密钥,每个数字都不相同,都在1-n之间,有一份长度小于等于n的信息,要求将信息放到密钥下边,一一对应,信息不足n的时候补空格,然后将位置重新排列,将此过程重复k次,求最后的字符串序列,最后的空格不用输出. 思路 :如果按照最原始的求循环结的话会超时,因为k值范围很大.所以要用置换群,把每个的元素的循环求出来,直接对其取余即可.会3270的话,这个题理解起来挺容易的. 1 //1126 2 #include <stdio.h> 3 #include <st

POJ 1159 Palindrome 题解

本题的题意理解之后,就是求最长回文子序列 longest palindrome subsequence,这里注意子序列和子串的区别. 有两种求法,一种是直接求,相当于填矩阵右上对角阵,另一种是转化为longest common subsequence的求法. 最大难点就是要求内存不能使用二维的. 故此第一种方法是有点难度的,因为需要把二维矩阵的对角线转化为一维表记录,对好下标就好了. 第二中方法会稍微容易点,效率都是一样的O(n*n). 方法1: #include <cstdio> const

POJ - Counterfeit Dollar 题解

挺考智力的题目. 思路: 1 如果是假币,那么每次都必定引起天平的不平衡 2 如果天平平横,那么全部都肯定是真币 利用这个特性,利用hash表,就能写出很简洁的程序. 如果使用枚举,那么会(轻松?)过百行的代码的. 当然其实题目给出了条件:一定可以找出唯一的假币的. 如果没有这个条件,那么是不一定可以三次称,就能确定结果的. 下面程序参考了别人的: http://www.cnblogs.com/orangeman/archive/2009/07/10/1520663.html 这个家伙的思路也不

UVa 127 - &quot;Accordian&quot; Patience POJ 1214 链表题解

UVa和POJ都有这道题. 不同的是UVa要求区分单复数,而POJ不要求. 使用STL做会比较简单,这里纯粹使用指针做了,非常麻烦的指针操作,一不小心就错.调试起来还是非常费力的 本题理解起来也是挺费力的,要搞清楚如何模拟也不容易啊,读题要很仔细. 纯指针的操作挺快的吧.不过POJ 0ms,而UVa就0.2左右了. 三相链表: 1 只要有叠起来的牌,那么就使用一个down指针指向下面的牌就可以了. 2 使用双向链表,可以方便前后遍历. 3 记得有了更新牌之后,又要重新开始检查是否需要更新牌,这是