藍橋杯BASIC 19 完美的代價

2021-10-10 01:48:18 字數 1407 閱讀 3707

csdn富文字編輯器測試,這樣子似乎沒有markdown好看欸

資源限制

時間限制:1.0s   記憶體限制:512.0mb

問題描述

回文串,是一種特殊的字串,它從左往右讀和從右往左讀是一樣的。小龍龍認為回文串才是完美的。現在給你乙個串,它不一定是回文的,請你計算最少的交換次數使得該串變成乙個完美的回文串。

交換的定義是:交換兩個相鄰的字元

例如mamad

第一次交換 ad : mamda

第二次交換 md : madma

第三次交換 ma : madam (回文!完美!)

輸入格式

第一行是乙個整數n,表示接下來的字串的長度(n <= 8000)

第二行是乙個字串,長度為n.只包含小寫字母

輸出格式

如果可能,輸出最少的交換次數。

否則輸出impossible

樣例輸入

5mamad

樣例輸出

本題的主要考點是貪心演算法,因此考慮最少交換次數可以看成每對元素中只有乙個元素進行單向移動。具體操作是,從左邊開始先固定乙個元素,然後從右邊開始掃瞄,尋找第乙個相同的元素,若能找到則將該元素移動到右邊相對應的位子並記錄交換的次數;若一直掃瞄到該左邊的元素自己,則說明未配對的該元素只有乙個,若n為偶數則說明不是回文串,若n為奇數則先計算該元素移到中間所需的次數並在後面的移動中跳過該元素,若第二次找到不能配對的元素則說明不是回文串。

在寫本題**時我自己遇到的幾個需要注意的點:

無需將偶數與奇數情況分開討論,n為奇數時增加乙個標誌位flag即可,可以使用flag來實現掃瞄與交換時跳過單個數的功能。

可以將外迴圈的i範圍設為0~n-1,因為當n-1-i+flag >= i時會自動跳過內迴圈;而一對初始位置都在中點右邊出現的元素會隨著其他元素的交換自動移動到中點左邊,因此無需多加考慮。

**中我使用了exit()函式來退出程式,但由於藍橋杯的系統要求main函式一定要return 0,因此若使用exit(1)則會被藍橋杯系統判定為「執行錯誤」,因此一定要使用exit(0)來退出程式。

#include using namespace std;

int main() {

int n;

int count = 0;

cin >> n;

string arr;

cin >> arr;

int flag = 0;

for(int i=0; i=i; j--){ //從後向前找

if(j==i) //當配對到自己時說明該元素只有乙個未配對

if(n%2==0){ //偶數情況

cout<<"impossible"<1){ //超過兩個元素不能配對

cout<<"impossible"《如有錯誤之處,望大佬們指正。

藍橋杯 Basic19 完美的代價

問題描述 回文串,是一種特殊的字串,它從左往右讀和從右往左讀是一樣的。小龍龍認為回文串才是完美的。現在給你乙個串,它不一定是回文的,請你計算最少的交換次數使得該串變成乙個完美的回文串。交換的定義是 交換兩個相鄰的字元 例如mamad 第一次交換 ad mamda 第二次交換 md madma 第三次...

藍橋Basic19完美的代價

問題描述 回文串,是一種特殊的字串,它從左往右讀和從右往左讀是一樣的。小龍龍認為回文串才是完美的。現在給你乙個串,它不一定是回文的,請你計算最少的交換次數使得該串變成乙個完美的回文串。交換的定義是 交換兩個相鄰的字元 例如mamad 第一次交換 ad mamda 第二次交換 md madma 第三次...

藍橋杯 BASIC 19 基礎練習 完美的代價

基礎練習 完美的代價 時間限制 1.0s 記憶體限制 512.0mb 問題描述 回文串,是一種特殊的字串,它從左往右讀和從右往左讀是一樣的。小龍龍認為回文串才是完美的。現在給你乙個串,它不一定是回文的,請你計算最少的交換次數使得該串變成乙個完美的回文串。交換的定義是 交換兩個相鄰的字元 例如mama...