bzoj 1031 [JSOI2007]字符加密Cipher(后缀数组)

2024-04-09 12:58

本文主要是介绍bzoj 1031 [JSOI2007]字符加密Cipher(后缀数组),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1031: [JSOI2007]字符加密Cipher

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 8411  Solved: 3742
[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

 

思路:

可以很容易地想到将一个字符串复制一份拼到后面去。然后我们用后缀数组处理出来sa数组,这样得到的就是按照从小到大排完序的数组了。所以我们只要去除掉在原始字符串后面位置的字符串就行了。然后按照题目要求输出就可以了。

 

代码:

#include<cstdio>
#include<algorithm>
#include<queue>
#include<iostream>
#include<cmath>
#include<cstring>
using namespace std;
const int MAXN=2e5+5;
const int inf=0x3f3f3f3f;
typedef long long ll;
int rmq[MAXN][20];
int n,k;
int wa[MAXN],wb[MAXN],wv[MAXN],wss[MAXN];
int sa[MAXN],ran[MAXN],height[MAXN];
int cmp(int *r,int a,int b,int l)
{return r[a]==r[b]&&r[a+l]==r[b+l];
}
void da(char *r,int *sa,int n,int m)
{int i,j,p,*x=wa,*y=wb,*t;for(i=0; i<m; i++) wss[i]=0;for(i=0; i<n; i++) wss[x[i]=(int)r[i]]++;for(i=1; i<m; i++) wss[i]+=wss[i-1];for(i=n-1; i>=0; i--) sa[--wss[x[i]]]=i;for(j=1,p=1; p<n; j*=2,m=p){for(p=0,i=n-j; i<n; i++) y[p++]=i;for(i=0; i<n; i++) if(sa[i]>=j) y[p++]=sa[i]-j;for(i=0; i<n; i++) wv[i]=x[y[i]];for(i=0; i<m; i++) wss[i]=0;for(i=0; i<n; i++) wss[wv[i]]++;for(i=1; i<m; i++) wss[i]+=wss[i-1];for(i=n-1; i>=0; i--) sa[--wss[wv[i]]]=y[i];for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1; i<n; i++)x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;}return;
}
void callheight(char *r,int *sa,int n)
{int i,j,k=0;for(i=1;i<=n;i++)ran[sa[i]]=i;for(i=0;i<n;height[ran[i++]]=k)for(k?k--:0,j=sa[ran[i]-1];r[i+k]==r[j+k];k++);return ;
}
char str[MAXN];
int ji[MAXN];
int main()
{cin>>str;int len=strlen(str);for(int i=0;i<len;i++){str[i+len]=str[i];}int len1=len*2;str[len1]='\0';da(str,sa,len1+1,130);int cnt=0;for(int i=1;i<=len1;i++){if(sa[i]>len-1) continue;ji[cnt++]=sa[i];}for(int i=0;i<cnt;i++){int pos=ji[i];printf("%c",str[pos+len-1]);}printf("\n");return 0;
}

 

这篇关于bzoj 1031 [JSOI2007]字符加密Cipher(后缀数组)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/888215

相关文章

Java 字符数组转字符串的常用方法

《Java字符数组转字符串的常用方法》文章总结了在Java中将字符数组转换为字符串的几种常用方法,包括使用String构造函数、String.valueOf()方法、StringBuilder以及A... 目录1. 使用String构造函数1.1 基本转换方法1.2 注意事项2. 使用String.valu

Go语言使用Buffer实现高性能处理字节和字符

《Go语言使用Buffer实现高性能处理字节和字符》在Go中,bytes.Buffer是一个非常高效的类型,用于处理字节数据的读写操作,本文将详细介绍一下如何使用Buffer实现高性能处理字节和... 目录1. bytes.Buffer 的基本用法1.1. 创建和初始化 Buffer1.2. 使用 Writ

Python在固定文件夹批量创建固定后缀的文件(方法详解)

《Python在固定文件夹批量创建固定后缀的文件(方法详解)》文章讲述了如何使用Python批量创建后缀为.md的文件夹,生成100个,代码中需要修改的路径、前缀和后缀名,并提供了注意事项和代码示例,... 目录1. python需求的任务2. Python代码的实现3. 代码修改的位置4. 运行结果5.

JAVA中整型数组、字符串数组、整型数和字符串 的创建与转换的方法

《JAVA中整型数组、字符串数组、整型数和字符串的创建与转换的方法》本文介绍了Java中字符串、字符数组和整型数组的创建方法,以及它们之间的转换方法,还详细讲解了字符串中的一些常用方法,如index... 目录一、字符串、字符数组和整型数组的创建1、字符串的创建方法1.1 通过引用字符数组来创建字符串1.2

Java中的密码加密方式

《Java中的密码加密方式》文章介绍了Java中使用MD5算法对密码进行加密的方法,以及如何通过加盐和多重加密来提高密码的安全性,MD5是一种不可逆的哈希算法,适合用于存储密码,因为其输出的摘要长度固... 目录Java的密码加密方式密码加密一般的应用方式是总结Java的密码加密方式密码加密【这里采用的

使用Python制作一个PDF批量加密工具

《使用Python制作一个PDF批量加密工具》PDF批量加密‌是一种保护PDF文件安全性的方法,通过为多个PDF文件设置相同的密码,防止未经授权的用户访问这些文件,下面我们来看看如何使用Python制... 目录1.简介2.运行效果3.相关源码1.简介一个python写的PDF批量加密工具。PDF批量加密

vue如何监听对象或者数组某个属性的变化详解

《vue如何监听对象或者数组某个属性的变化详解》这篇文章主要给大家介绍了关于vue如何监听对象或者数组某个属性的变化,在Vue.js中可以通过watch监听属性变化并动态修改其他属性的值,watch通... 目录前言用watch监听深度监听使用计算属性watch和计算属性的区别在vue 3中使用watchE

hdu2241(二分+合并数组)

题意:判断是否存在a+b+c = x,a,b,c分别属于集合A,B,C 如果用暴力会超时,所以这里用到了数组合并,将b,c数组合并成d,d数组存的是b,c数组元素的和,然后对d数组进行二分就可以了 代码如下(附注释): #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<que

hdu 1166 敌兵布阵(树状数组 or 线段树)

题意是求一个线段的和,在线段上可以进行加减的修改。 树状数组的模板题。 代码: #include <stdio.h>#include <string.h>const int maxn = 50000 + 1;int c[maxn];int n;int lowbit(int x){return x & -x;}void add(int x, int num){while

C语言:柔性数组

数组定义 柔性数组 err int arr[0] = {0}; // ERROR 柔性数组 // 常见struct Test{int len;char arr[1024];} // 柔性数组struct Test{int len;char arr[0];}struct Test *t;t = malloc(sizeof(Test) + 11);strcpy(t->arr,