1031: [JSOI2007]字符加密Cipher
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 7882 Solved: 3425
[Submit][Status][Discuss]
Description
喜欢钻研问题的JS同学,最近又迷上了对加密方法的思考。一天,他突然想出了一种他认为是终极的加密办法
:把需要加密的信息排成一圈,显然,它们有很多种不同的读法。例如下图,可以读作:
JSOI07 SOI07J OI07JS I07JSO 07JSOI 7JSOI0把它们按照字符串的大小排序:07JSOI 7JSOI0 I07JSO JSOI07
OI07JS SOI07J读出最后一列字符:I0O7SJ,就是加密后的字符串(其实这个加密手段实在很容易破解,鉴于这是
突然想出来的,那就^^)。但是,如果想加密的字符串实在太长,你能写一个程序完成这个任务吗?
Input
输入文件包含一行,欲加密的字符串。注意字符串的内容不一定是字母、数字,也可以是符号等。
Output
输出一行,为加密后的字符串。
Sample Input
JSOI07
Sample Output
I0O7SJ
HINT
对于100%的数据字符串的长度不超过100000。
Source
后缀数组裸题。。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <algorithm> 6 #include <queue> 7 #include <vector> 8 #include <cmath> ?9 #define min(a, b) ((a) < (b) ? (a) : (b))10 #define max(a, b) ((a) > (b) ? (a) : (b))11 #define abs(a) ((a) < 0 ? (-1 * (a)) : (a))12 template <class T>13 inline void swap(T &a, T &b)14 {15 ????T tmp = a;a = b;b = tmp;16 }17 inline void read(int &x)18 {19 ????x = 0;char ch = getchar(), c = ch;20 ????while(ch < ‘0‘ || ch > ‘9‘) c = ch, ch = getchar();21 ????while(ch <= ‘9‘ && ch >= ‘0‘) x = x * 10 + ch - ‘0‘, ch = getchar();22 ????if(c == ‘-‘) x = -x;23 }24 const int INF = 0x3f3f3f3f;25 const int MAXN = 1000000 + 10;26 char s[MAXN];27 int sa[MAXN], tmp[MAXN], tmp2[MAXN], c[MAXN], n, m;28 void build(char *s, int *sa, int n, int m)29 {30 ????int i, *x = tmp, *y = tmp2;31 ????for(i = 0; i < m; i++) c[i] = 0;32 ????for(i = 0; i < n; i++) ++ c[x[i] = s[i]];33 ????for(i = 1; i < m; i++) c[i] += c[i-1];34 ????for(i = n - 1; i >= 0; i--) sa[--c[x[i]]] = i;35 ????for(int k = 1; k <= n; k <<= 1) 36 ????{37 ????????int p = 0;38 ????????for(i = n - k; i < n; i++) y[p++] = i;39 ????????for(i = 0; i < n; i++) if(sa[i] >= k) y[p++] = sa[i] - k;40 ?????????for(i = 0; i < m; i++) c[i] = 0;41 ????????for(i = 0; i < n; i++) ++ c[x[y[i]]];42 ????????for(i = 0; i < m; i++) c[i] += c[i - 1];43 ????????for(i = n - 1; i >= 0; i --) sa[-- c[x[y[i]]]] = y[i];44 ????????swap(x, y);45 ????????p = 1; x[sa[0]] = 0;46 ????????for(i = 1; i < n; i++)47 ????????????x[sa[i]] = y[sa[i - 1]] == y[sa[i]] && y[sa[i - 1] + k] == y[sa[i] + k] ? p - 1 : p ++;48 ????????if(p >= n) break;49 ?????????m = p;50 ????}51 }52 int main()53 {54 ????scanf("%s", s);55 ????n = strlen(s);56 ????for(register int i = 0;i < n;++ i) s[n + i] = s[i], m = max(m, s[i] + 1);57 ????build(s, sa, (n << 1) | 1, m);58 ????for(int i = 1;i <= (n << 1);++ i)59 ????{60 ????????if(sa[i] < n) ???61 ????????????printf("%c", s[sa[i] + n - 1]);62 ????}63 ????return 0;64 }
BZOJ1031: [JSOI2007]字符加密Cipher
原文地址:https://www.cnblogs.com/huibixiaoxing/p/8328199.html