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

    [JSOI2007]字符加密Cipher

    题目

    喜欢钻研问题的JS同学,最近又迷上了对加密方法的思考。一天,他突然想出了一种他认为是终极的加密办法:把需要加密的信息排成一圈,显然,它们有很多种不同的读法。例如下图,可以读作:
    JSOI07 SOI07J OI07JS I07JSO 07JSOI 7JSOI0把它们按照字符串的大小排序:07JSOI 7JSOI0 I07JSO JSOI07 OI07JS SOI07J读出最后一列字符:I0O7SJ,就是加密后的字符串(其实这个加密手段实在很容易破解,鉴于这是突然想出来的,那就^^)。但是,如果想加密的字符串实在太长,你能写一个程序完成这个任务吗?

    INPUT

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

    OUTPUT

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

    SAMPLE

    INPUT

    JSOI07

    OUTPUT

    I0O7SJ

    解题报告

    第一道不是板子题的$SA$(这tm不是板子题?)

    首先,因为这玩意是个环,所以我们把串翻倍

    然后跑一遍板子,求出$SA$

    接下来就是怎么用的问题了

    我们知道,$SA[i]$表示第$i$个后缀的首位置下标,所以我们可以找到对应每个排名的下标,对应输出相应字符即可

     1 #include <iostream>
     2 #include <cstring>
     3 #include <cstdio>
     4 using namespace std;
     5 char ch[100005],s[200010];
     6 int len;
     7 int n,m;
     8 int t1[200010],t2[200010],t3[200010],buc[200010];
     9 int sa[200010],rank[200010];
    10 inline void Suffix(){
    11     int i,j,k(0),p(0),*x(t1),*y(t2),*t;
    12     for(i=0;i<=m;++i)buc[i]=0;
    13     for(i=1;i<=n;++i)++buc[x[i]=s[i]];
    14     for(i=1;i<=m;++i)buc[i]+=buc[i-1];
    15     for(i=n;i>=1;--i)sa[buc[x[i]]--]=i;
    16     for(j=1;p<n;j<<=1,m=p){
    17         for(p=0,i=n-j+1;i<=n;++i)y[++p]=i;
    18         for(i=1;i<=n;++i)
    19             if(sa[i]-j>0)
    20                 y[++p]=sa[i]-j;
    21         for(i=0;i<=m;++i)buc[i]=0;
    22         for(i=1;i<=n;++i)t3[i]=x[y[i]];
    23         for(i=1;i<=n;++i)++buc[t3[i]];
    24         for(i=1;i<=m;++i)buc[i]+=buc[i-1];
    25         for(i=n;i>=1;--i)sa[buc[t3[i]]--]=y[i];
    26         for(t=x,x=y,y=t,p=1,x[sa[1]]=1,i=2;i<=n;++i)
    27             x[sa[i]]=((y[sa[i]]==y[sa[i-1]])&&(y[sa[i]+j]==y[sa[i-1]+j]))?p:++p;
    28     }
    29     for(i=1;i<=n;++i)rank[sa[i]]=i;
    30 }
    31 inline char get(int x){
    32     int tmp(sa[x]);//cout<<x<<" "<<tmp<<endl;
    33     tmp=tmp+len-1;
    34     if(tmp>n)
    35         tmp-=len;
    36     return s[tmp];
    37 }
    38 int main(){
    39     scanf("%s",ch);
    40     len=strlen(ch);
    41     for(int i=1;i<=len;++i)
    42         s[i]=ch[i-1];
    43     for(int i=1;i<=len;++i)
    44         s[len+i]=ch[i-1];
    45     n=len<<1;
    46     m=130;
    47     Suffix();
    48     for(int i=2;i<=n;i+=2)
    49         putchar(get(i));
    50 }
    View Code
  • 相关阅读:
    Json基本使用方法
    Java编程思想(20170818)
    FireFox加载Lodop控件
    泛型
    设计模式原则
    设计模式
    设计模式3.1:简单工厂模式
    设计模式2,模板方法
    spring -- AutoCloseable 作用
    spring 源码方法概要
  • 原文地址:https://www.cnblogs.com/hzoi-mafia/p/7570990.html
Copyright © 2011-2022 走看看