首先我們知道了如何交換位置,只能相鄰才能交換。
用兩個循環,一個從左邊,一個從右邊開始遍歷,分兩種情況:
①如果左邊字符等於右邊字符,說明,這個字符是成對的(目前),然後利用下標計算出需要移動的距離(與移動次數相等),記錄下來,然後遍歷把每個字符的位置往前移動一個位置,更新字符串,變成移動後的樣子
②判斷兩個循環是否相遇,如果相遇說明,需要匹配的字符不存在,
如果字符長度爲偶數,直接Impossible,
如果不是偶數,記錄這一次,如果達到第二次,那麼也不可能是完美字符串,
如果以上都沒有發生,那麼需要記錄這個字符移動到中間位置的距離,注意這個字符是不需要真正移動的,因爲我們可以略過去,不影響以後的計算,以爲以後的計算都是兩點的距離,與開頭結尾的位置無關。
例如字符串
macmacd
12345678
m與d不同,m與c不同,最終到了m與m,1位置和4位置,4-1=3,移動三次,維護字符串爲
macmacdm
下一次循環的時候就從a與d比較開始,縮短比較的長度
#include<iostream>
using namespace std;
int main() {
int n, len, flag = 0, index, ans = 0;
char str[8005];
cin >> len;
cin >> str+1;
n = len;//記錄初始長度
for(int i = 1; i <= n; i++) {
for(int j = n; j >= 1; j--) {
if(i == j) {
flag++;//記錄次數
if(len%2==0 || flag > 1) {//如果有一次並且是偶數長度,肯定不行,flag==2,說明有兩次,奇數個數也不行
cout << "Impossible" << endl;
return 0;
}
index = len/2 - i + 1;//移動到中間位置的步數
break;
}
else if(str[i] == str[j]) {
ans += n - j;//移動的距離
for(int l = j; l < n; l++) {
str[l] = str[l+1];//往前移動
}
str[n] = str[i];//維護字符串爲移動後
n--;//略過已經移動好的,下一次遍歷就從沒有判定的地方開始
break;
}
}
}
cout << ans+index << endl;
return 0;
}