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

    [BZOJ1031][JSOI2007]字符加密Cipher

    试题描述

    喜欢钻研问题的JS同学,最近又迷上了对加密方法的思考。一天,他突然想出了一种他认为是终极的加密办法
    :把需要加密的信息排成一圈,显然,它们有很多种不同的读法。例如下图,可以读作:

     

    JSOI07 SOI07J OI07JS I07JSO 07JSOI 7JSOI0把它们按照字符串的大小排序:07JSOI 7JSOI0 I07JSO JSOI07
     OI07JS SOI07J读出最后一列字符:I0O7SJ,就是加密后的字符串(其实这个加密手段实在很容易破解,鉴于这是
    突然想出来的,那就^^)。但是,如果想加密的字符串实在太长,你能写一个程序完成这个任务吗?

    输入

    输入文件包含一行,欲加密的字符串。注意字符串的内容不一定是字母、数字,也可以是符号等。

    输出

    输出一行,为加密后的字符串。

    输入示例

    JSOI07

    输出示例

    I0O7SJ

    数据规模及约定

    对于100%的数据字符串的长度不超过100000。

    题解

    把字符串复制一遍后缀排序。

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cctype>
    #include <algorithm>
    #include <vector>
    using namespace std;
    
    int read() {
    	int x = 0, f = 1; char c = getchar();
    	while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
    	while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
    	return x * f;
    }
    
    #define maxn 400010
    
    char S[maxn];
    int n, x[maxn], y[maxn], sa[maxn], Ws[maxn];
    
    bool cmp(int* a, int p1, int p2, int l) { return a[p1] == a[p2] && a[p1+l] == a[p2+l]; }
    void ssort() {
    	int m = 0;
    	for(int i = 1; i <= n; i++) Ws[x[i] = S[i]]++, m = max(m, x[i]);
    	for(int i = 1; i <= m; i++) Ws[i] += Ws[i-1];
    	for(int i = n; i; i--) sa[Ws[x[i]]--] = i;
    	for(int j = 1, pos; pos < n; j <<= 1, m = pos) {
    		pos = 0;
    		for(int i = n - j + 1; i <= n; i++) y[++pos] = i;
    		for(int i = 1; i <= n; i++) if(sa[i] > j) y[++pos] = sa[i] - j;
    		for(int i = 1; i <= m; i++) Ws[i] = 0;
    		for(int i = 1; i <= n; i++) Ws[x[i]]++;
    		for(int i = 1; i <= m; i++) Ws[i] += Ws[i-1];
    		for(int i = n; i; i--) sa[Ws[x[y[i]]]--] = y[i];
    		swap(x, y); pos = 1; x[sa[1]] = 1;
    		for(int i = 2; i <= n; i++) x[sa[i]] = cmp(y, sa[i], sa[i-1], j) ? pos : ++pos;
    	}
    	return ;
    }
    
    int main() {
    	scanf("%s", S + 1);
    	
    	n = strlen(S + 1);
    	for(int i = n + 1; i <= (n << 1); i++) S[i] = S[i-n];
    	n <<= 1;
    	ssort();
    	for(int i = 1; i <= n; i++) if(sa[i] <= (n >> 1)) putchar(S[sa[i]-1?sa[i]-1:n]); putchar('
    ');
    	
    	return 0;
    }
    
  • 相关阅读:
    进程与线程
    the art of seo(chapter seven)
    the art of seo(chapter six)
    the art of seo(chapter five)
    the art of seo(chapter four)
    the art of seo(chapter three)
    the art of seo(chapter two)
    the art of seo(chapter one)
    Sentinel Cluster流程分析
    Sentinel Core流程分析
  • 原文地址:https://www.cnblogs.com/xiao-ju-ruo-xjr/p/6485732.html
Copyright © 2011-2022 走看看