洛谷 P1709 隐藏口令

题目描述

有时候程序员有很奇怪的方法来隐藏他们的口令。Binny会选择一个字符串S(由N个小写字母组成,5<=N<=5,000,000),然后他把S顺时针绕成一个圈,每次取一个做开头字母并顺时针依次取字母而组成一个字符串。这样将得到一些字符串,他把它们排序后取出第一个字符串。把这个字符串的第一个字母在原字符串中的位置-1做为口令。

如字符串alabala,按操作的到7个字符串,排序后得:

aalabal

abalaal

alaalab

alabala

balaala

laalaba

labalaa

第一个字符串为aalabal,这个a在原字符串位置为7,7-1=6,则6为口令。

输入输出格式

输入格式:

第一行:一个数:N

第二行开始:字符串:S(每72个字符一个换行符)

输出格式:

一行,为得到的口令

输入输出样例

输入样例#1: 复制
7
anabana
输出样例#1: 复制
6

说明

题目满足:

30%的数据n<=10000

70%的数据n<=100000

100%的数据n<=5000000

时限 1s

题目翻译来自NOCOW。

USACO Training Section 5.5

//20170523新增数据四组

分析:

这道题很明显是一个字符串最小表示的问题,在原先的博客中我也发过这个算法,主要是在处理字符串的时候要有特殊的技巧,因为数据量比较大,不能用常规的字符串进行接收。

代码:

 1 import java.io.BufferedReader;
 2 import java.io.IOException;
 3 import java.io.InputStreamReader;
 4 import java.util.Scanner;
 5 
 6 public class Main {
 7     public static void main(String args[]) throws IOException {
 8         Scanner sc=new Scanner(System.in);
 9         int num=sc.nextInt();
10         char[] c=new char[num];
11         String str;
12         int ll;
13         int now=0;
14         while(sc.hasNext()) {
15             str=sc.next();
16             ll=str.length();
17             for(int n=0;n<ll;++n)
18                 c[now+n]=str.charAt(n);
19             now+=ll;
20             if(now==num)
21                 break;
22         }
23         System.out.print(res(c,num));
24     }
25     public static int res(char[] c,int len) {
26         int i=0,j=1,k=0;
27         while(i<len&&j<len&&k<len) {
28             if(c[(i+k)%len]==c[(j+k)%len])
29                 k++;
30             else if(c[(i+k)%len]<c[(j+k)%len]) {
31                 j=j+k+1;
32                 k=0;
33             }
34             else {
35                 i=j;
36                 j=i+1;
37                 k=0;
38             }
39         }
40         return i;
41     }
42 }
原文地址:https://www.cnblogs.com/CHAHA123/p/10874115.html