基礎練習 完美的代價(藍橋杯 字符串問題)

首先我們知道了如何交換位置,只能相鄰才能交換。

用兩個循環,一個從左邊,一個從右邊開始遍歷,分兩種情況:
①如果左邊字符等於右邊字符,說明,這個字符是成對的(目前),然後利用下標計算出需要移動的距離(與移動次數相等),記錄下來,然後遍歷把每個字符的位置往前移動一個位置,更新字符串,變成移動後的樣子
②判斷兩個循環是否相遇,如果相遇說明,需要匹配的字符不存在,
如果字符長度爲偶數,直接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;
}
發佈了155 篇原創文章 · 獲贊 16 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章