算法練習普通(完美的代價)

而浮生若夢,爲歡幾何?
點贊再看,養成習慣。

在這裏插入圖片描述

問題描述

迴文串,是一種特殊的字符串,它從左往右讀和從右往左讀是一樣的。小龍龍認爲迴文串纔是完美的。現在給你一個串,它不一定是迴文的,請你計算最少的交換次數使得該串變成一個完美的迴文串。
  交換的定義是:交換兩個相鄰的字符
  例如mamad
  第一次交換 ad : mamda
  第二次交換 md : madma
  第三次交換 ma : madam (迴文!完美!)
  
輸入格式
  第一行是一個整數N,表示接下來的字符串的長度(N <= 8000)
  第二行是一個字符串,長度爲N.只包含小寫字母

輸出格式
  如果可能,輸出最少的交換次數。
  否則輸出Impossible

樣例輸入
5
mamad

樣例輸出
3

import java.util.Scanner;

public class ThePriceOfPerfection {

	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		while(sc.hasNext()) {
			int n=sc.nextInt();
			String st=sc.next();
			char[] ch=st.toCharArray();
			int i , j , k = 0 , cnt = 0 , sing = 0 , end = n - 1;
			//sing用來記錄只出現一次的字母個數
			for ( i = 0; i < end; i++) { //從左邊第一個開始,從右邊掃描尋找第一個與左邊相同的字母
				for ( j = end; j >= 0 ; j--) {
					if( j == i ) {		//說明走到了單個字母那裏
						sing++;			//記錄個數
						if( sing > 1 || n % 2 == 0) {	//如果字母長度爲奇數並且單個字母個數多餘一個或者如果字母長度爲偶數但是出現了單個字母
							System.out.println("Impossible");
							k = 1;
							break;
						}
						cnt += n / 2 - i;	//說明字母長度爲奇數且單個字母只有一個,那麼將它移到最中間
						break;
					}else{
					if( ch[ j ] == ch[ i ]) {	//右邊找到了,將所有字母從右往左進行移動
						for (int l = j; l < end; l++) 
							ch[ l ] = ch[ l + 1 ];
							ch[ end ] = ch [ i ];	//滿足迴文的字母排出去
							cnt += end - j;
							end--;		//縮小邊界
							break;
						}
					}
				}
				if( k == 1 )
					break;
			}
			if( k == 0 )
				System.out.println(cnt);
		}
	}
}

hasNext()
while(sc.hasNext())
CharArray()

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章