一 问题描述
X星球的考古学家发现了一批古代留下来的密码。
这些密码是由A、B、C、D 四种植物的种子串成的序列。
仔细分析发现,这些密码串当初应该是前后对称的(也就是我们说的镜像串)。
由于年代久远,其中许多种子脱落了,因而可能会失去镜像的特征。
你的任务是:
给定一个现在看到的密码串,计算一下从当初的状态,它要至少脱落多少个种子,才可能会变成现在的样子。
输入一行,表示现在看到的密码串(长度不大于1000)
要求输出一个正整数,表示至少脱落了多少个种子。
例如,输入:
ABCBA
则程序应该输出:
0
再例如,输入:
ABDCDCBABC
则程序应该输出:
3
资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 3000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意:不要使用package语句。不要使用jdk1.7及以上版本的特性。
注意:主类的名字必须是:Main,否则按无效代码处理。
思路:
题目中给出了这是一个镜像串(正着读和倒着读是一样的),因为年代久远所以有一些字符不见了,现在我们需要补充n个字符才能让他恢复成原来的样子,但是这题有特殊情况,比如原先是abcba,脱落后变成aca,而aca是符合题目要求的,所以我们的输入不是2而是0。
这样子,我们只需要把题目给的字符串a变成镜像串就可以了。如何变?首先我们先得到a的反串b(例如:abc的反串为cba),求出a与b的最长公共子序列,由a的长度减去最长公共子序列的长度就是我们所求的答案。
不懂最长公共子序列的可以了解下:最长公共子序列
import java.util.Scanner;
public class Main {
public static String str;
public static String str2;
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner read = new Scanner(System.in);
str = read.nextLine();
read.close();
str2 = "";
for(int i=str.length()-1;i>=0;i--)
{
str2+=String.valueOf(str.charAt(i));
}
int [][]result = new int[str.length()+1][str.length()+1];
for(int i=1;i<=str.length();i++)
for(int j=1;j<=str.length();j++)
{
if(str.charAt(i-1) == str2.charAt(j-1))
result[i][j] = result[i-1][j-1]+1;
else
result[i][j] = Math.max(result[i-1][j], result[i][j-1]);
}
int min = str.length()-result[str.length()][str.length()];
System.out.println(min);
}
}