1. 程式人生 > >【藍橋杯】基礎訓練 完美的代價

【藍橋杯】基礎訓練 完美的代價

問題描述
  迴文串,是一種特殊的字串,它從左往右讀和從右往左讀是一樣的。小龍龍認為迴文串才是完美的。現在給你一個串,它不一定是迴文的,請你計算最少的交換次數使得該串變成一個完美的迴文串。
  交換的定義是:交換兩個相鄰的字元
  例如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 {// 可以得到完美迴文字串,求最少操作次數

		}
	}
}