首页 > 代码库 > POJ 1026 Cipher 题解
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; }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。