【藍橋杯】基礎訓練 完美的代價
阿新 • • 發佈:2018-12-09
問題描述 迴文串,是一種特殊的字串,它從左往右讀和從右往左讀是一樣的。小龍龍認為迴文串才是完美的。現在給你一個串,它不一定是迴文的,請你計算最少的交換次數使得該串變成一個完美的迴文串。 交換的定義是:交換兩個相鄰的字元 例如mamad 第一次交換 ad : mamda 第二次交換 md : madma 第三次交換 ma : madam (迴文!完美!) 輸入格式 第一行是一個整數N,表示接下來的字串的長度(N <= 8000) 第二行是一個字串,長度為N.只包含小寫字母 輸出格式 如果可能,輸出最少的交換次數。 否則輸出Impossible 樣例輸入 5 mamad 樣例輸出 3
思路:(1)判斷是否可以構成迴文串
①形如“mama”,每個字元出現次數都是偶數次,可以得到完美迴文串“maam”或者“amma”
②形如“mamad”,只有1個字元出現次數是奇數次,其餘的都是偶數次,可以得到完美迴文串“madam”或者“amdma”
③形如“mamade”,有2字元出現次數是奇數次,取餘的都是偶數次,得不到完美迴文串
以此類推,我們可以發現,字串中的“出現奇數次的字元”大於等於2個的時候,是不能得到完美迴文串的,這時輸出是“Impossible”
(2)貪心演算法求最少交換次數
由於本渣渣貪心演算法未學習,又想不到其他方法,等今晚學習學習,再看看。
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); String str = sc.next(); int sum = 0;// 出現奇數次的字元個數 for (int i = 0; i < str.length(); i++) { int book = 1;// 該字元出現的次數 for (int j = i; j >= 0; j--) {// 確保該字元在之前沒有出現過 if (str.charAt(i) == str.charAt(j)) break; else { for (int k = i + 1; k < str.length(); k++) { if (str.charAt(i) == str.charAt(k)) book++; } } } if (book % 2 == 1)// 判斷該字元出現的次數是否為奇數 sum++; } if (sum >= 2)// 無法得到完美迴文字串 System.out.println("Impossible"); else {// 可以得到完美迴文字串,求最少操作次數 } } }