zoukankan      html  css  js  c++  java
  • BZOJ1031: [JSOI2007]字符加密Cipher

    1031: [JSOI2007]字符加密Cipher

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 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, m);
    58     for(int i = 0;i < (n << 1);++ i)
    59         if(sa[i] < n) printf("%c", s[sa[i] + n - 1]);
    60     return 0;
    61 }
    BZOJ1031
  • 相关阅读:
    我的航拍直升机 控制基站软件的编写历程(2.2)——Qt Creator 版本控制系统
    windows下QT开发环境建立方法
    QT 4.5 windows版本 安装问题 及 Junction 使用
    各种平台下编译qt工程
    华为面试题
    strcpy,strncpy,strlcpy,memcpy
    QT/E 更换字体问题
    Linux设备驱动编程中断处理
    oracle数据库连接池的使用
    Windows下QT的安装
  • 原文地址:https://www.cnblogs.com/huibixiaoxing/p/8328199.html
Copyright © 2011-2022 走看看