资源限制
时间限制:1.0s 内存限制:512.0MB
问题描述
回文串,是一种特殊的字符串,它从左往右读和从右往左读是一样的。小龙龙认为回文串才是完美的。现在给你一个串,它不一定是回文的,请你计算最少的交换次数使得该串变成一个完美的回文串。
交换的定义是:交换两个相邻的字符
例如mamad
第一次交换 ad : mamda
第二次交换 md : madma
第三次交换 ma : madam (回文!完美!)
输入格式
第一行是一个整数N,表示接下来的字符串的长度(N <= 8000)
第二行是一个字符串,长度为N.只包含小写字母
输出格式
如果可能,输出最少的交换次数。
否则输出Impossible
样例输入
5
mamad
样例输出
3
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int n = input.nextInt();
String str = input.next();
input.close();
System.out.println(helper2(str, n));
}
public static String helper1(String str) {
int n = str.length();
int total = 0;
List<Character> m = new ArrayList<>();
for (int i = 0; i < n; i++) {
m.add(str.charAt(i));
}
int k = 0;
for (int i = 0; i < n - 1; i++) {
for (int j = n - 1 - k; j > i; j--) {
if (m.get(i) == m.get(j)) {
total = total + (n - k - j - 1);
char a = m.get(j);
m.remove(j);
m.add(((n - 1) - k), a);
k++;
/*//交换过程数据
System.out.println(i + "\tremove " + j + "\tadd " + (n - 1 - k) + "\tpath " + (n - k - j - 1) + "\ttotal " + total);
for (Character character : m) {
System.out.print(character);
}
System.out.println();*/
break;
}
}
}
if (str.length() % 2 == 1) {
int a = n / 2;
int b = helper3(m);
total = total + (Math.abs(a - b));
/*//求回文结果时需要以下代码
m.add((a + 1), m.get(b));
m.remove(b);
*/
}
/*//回文排序结果,题中并未给出该要求
for (Character character : m) {
System.out.print(character);
}
System.out.println();*/
return String.valueOf(total);
}
public static String helper2(String str, int n) {
if (n <= str.length()) {
n = str.length();
} else
str = str.substring(0, n);
StringBuilder s = new StringBuilder(str);
for (int i = 0; i < s.length() - 1; i++) {
for (int j = i + 1; j < s.length(); j++) {
if (s.charAt(i) == s.charAt(j)) {
s.delete(j, j + 1);
break;
}
}
}
boolean a = (n % 2 == 1) && (n - 1) == 2 * (s.length() - 1);
boolean b = (n % 2 == 0) && (n == 2 * s.length());
if (a || b) {
return helper1(str);
} else
return "Impossible";
}
public static int helper3(List<Character> m) {
for (int i = 0; i <= (m.size() / 2); i++) {
if ((i == (m.size() / 2)) || (m.get(i) != m.get(m.size() - 1 - i))) {
return i;
}
}
return -1;
}
}
/*方法说明:
* helper1 求出回文过程的最少交换次数
* helper2 判断是否回文
* helper3 当目标串长度为奇数时,确定字符串中间字符位置
* */