Algorithmic Training Tricky and Clever Password Time limit: 2.0s memory limit: 256.0MB Problem Description When we were young, the hero in our story, King Copa, had his personal data not completely hidden.This is unacceptable to him.As a result, he developed a password that was easy to remember and difficult to crack.Later, he learned that the password was an odd-length palindrome string. Copa was afraid of forgetting his password, so he decided to write it on a piece of paper.He found it unsafe to save the password in this way, so he decided to encrypt the password as follows: he chose an integer X, which guarantees that X is not less than 0 and that 2X is strictly less than the length of the string.Then he divides the password into three sections, one for the first X characters, one for the last X characters, and one for the rest of the characters.You might call these three paragraphs prefix, suffix, middle in turn.Obviously, the length of middles is an odd number greater than 0, and prefix and suffix are equal.His encrypted password is A + prefix + B + middle + C + suffix, where A, B, C are three strings selected by Copa, all of which may be empty, + means the strings are connected. Many years have passed.Copa found the paper that wrote the encrypted string yesterday.However, Copa forgot the original password, A, B, C.Now he asks you to find a password as long as possible so that it can be invented, encrypted and written down by Copa in that year. Input Format Enter a string containing only the lowercase Latin letters, ranging in length from 1 to 10^5. Output Format The first line contains an integer k, which indicates how many non-empty strings are in the three parts of the original password you found.Obviously K in {1,3}.The next K rows, each with two integers, x_i_i, separated by spaces, represent the starting position and length of this section.Requires that the output x_i be incremented. The starting position x_i should be between 1 and the encrypted string length.l_i must be a positive integer because you only need to output information for non-empty parts.The length of middle s must be odd. If you have more than one set of answers, any one will do.Tip: You want to maximize the sum of the l_i output, not the k output. sample input abacaba sample output 1 1 7 sample input axbya sample output 3 1 1 2 1 5 1 sample input xabyczba sample output 3 2 2 4 1 7 2 Data size and conventions For 10% of data: n <= 10 For 30% of the data: n <= 100 For 100% data: n <= 100000 There is 20% data, output file first behavior 1.
package com.sihai.advance;
import java.util.ArrayList;
import java.util.Scanner;
public class Main{
public int[] getMaxReverse(char[] arrayA, int i, int j) {
int[] result = new int[2];
int max = 1;
int begin = i+1; //Beginning position of maximum palindrome string, initialized to position of character i
int zero = i; //Save the initial value of i
for(i = i + 1;i < j;i++) {
int start = i - 1;
int end = i + 1;
int count = 1;
while(start >= zero && end <= j) { //In this case, only odd-digit palindromes are returned
if(arrayA[start] == arrayA[end]) {
start--;
end++;
count = count + 2;
}
else
break;
}
if(count > max) {
max = count;
begin = i - (count-1)/2 + 1;
}
}
result[0] = begin; //Maximum palindrome string start position
result[1] = max; //Maximum palindrome string length
return result;
}
//Use KMP pattern matching to calculate the next function value
public int[] getNext(char[] arrayB) {
int[] next = new int[arrayB.length + 1];
int j = 0;
for(int i = 1;i < arrayB.length;i++) {
while(j > 0 && arrayB[i] != arrayB[j]) j = next[j];
if(arrayB[i] == arrayB[j]) j++;
next[i+1] = j;
}
return next;
}
//Using the KMP algorithm, find the character array arrayB, where the first match occurs in arrayA
public int getKmpFirstPosition(char[] arrayA, char[] arrayB) {
int position = -1;
int j = 0;
int[] next = getNext(arrayB);
for(int i = 0;i < arrayA.length;i++) {
while(j > 0 && arrayA[i] != arrayB[j]) j = next[j];
if(arrayA[i] == arrayB[j])
j++;
if(j == arrayB.length) {
position = i - j + 1;
break;
}
}
return position;
}
public void printResult(String A) {
//When the integer X = 0 is selected, the first behavior of output is 1, where only the longest palindrome string can be found directly in A, when the password is the longest
char[] arrayA = A.toCharArray();
int[] result0 = getMaxReverse(arrayA, 0, arrayA.length-1);
int maxLen0 = result0[1]; //Get the maximum length of the palindrome string at this time
//When X!= 0, the longest password must end at the end of the input string, that is, suffix is not empty
int j = arrayA.length - 1;
int maxLen = 0; //Used to calculate maximum password, initialized to 0
int position1 = 0;
int position2 = 0;
int position3 = 0;
int len1 = 0;
int len2 = 0;
for(int lenS = 1;lenS < arrayA.length/2;lenS++) {
char[] tempS = new char[lenS];
for(int a = 0;a < lenS;a++)
tempS[a] = arrayA[j-a];
if(getKmpFirstPosition(arrayA, tempS) == -1) {
continue;
}
int tempPosition1 = getKmpFirstPosition(arrayA, tempS) + 1;
int endPosition1 = tempPosition1+lenS;
int startPosition3 = arrayA.length-lenS;
if(startPosition3 <= endPosition1)
continue;
int[] result = getMaxReverse(arrayA,tempPosition1+lenS-1,j-lenS);
int tempLen2 = result[1];
int tempPosition2 = result[0];
if(lenS * 2 + tempLen2 > maxLen) {
position1 = tempPosition1;
position2 = tempPosition2;
position3 = j - lenS + 2;
len1 = lenS;
len2 = tempLen2;
maxLen = lenS * 2 + tempLen2;
}
}
if(maxLen0 >= maxLen) {
System.out.println("1");
System.out.println(result0[0]+" "+result0[1]);
} else {
System.out.println("3");
System.out.println(position1+" "+len1);
System.out.println(position2+" "+len2);
System.out.println(position3+" "+len1);
}
}
public static void main(String[] args){
Main test = new Main();
Scanner in = new Scanner(System.in);
// System.out.println("Please enter a string:");
String A = in.nextLine();
test.printResult(A);
}
}
Run result:
Please enter a string:
asdfsfaaaaa
1
7 5