日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

完美的代价 c语言,蓝桥杯基础练习 完美的代价

發(fā)布時(shí)間:2025/4/16 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 完美的代价 c语言,蓝桥杯基础练习 完美的代价 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

基礎(chǔ)練習(xí) 完美的代價(jià)

問(wèn)題:

問(wèn)題描述

回文串,是一種特殊的字符串,它從左往右讀和從右往左讀是一樣的。小龍龍認(rèn)為回文串才是完美的。現(xiàn)在給你一個(gè)串,它不一定是回文的,請(qǐng)你計(jì)算最少的交換次數(shù)使得該串變成一個(gè)完美的回文串。

交換的定義是:交換兩個(gè)相鄰的字符

例如mamad

第一次交換 ad : mamda

第二次交換 md : madma

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

輸入格式

第一行是一個(gè)整數(shù)N,表示接下來(lái)的字符串的長(zhǎng)度(N <= 8000)

第二行是一個(gè)字符串,長(zhǎng)度為N.只包含小寫(xiě)字母

輸出格式

如果可能,輸出最少的交換次數(shù)。

否則輸出Impossible

樣例輸入

5

mamad

樣例輸出

3

需要了解:

這道題的關(guān)鍵字是貪心算法,去百度了一下貪心算法,簡(jiǎn)單來(lái)說(shuō)就是在對(duì)問(wèn)題求解時(shí),總是做出在當(dāng)前看來(lái)是最好的選擇。也就是說(shuō),不從整體最優(yōu)上加以考慮,他所做出的僅是在某種意義上的局部最優(yōu)解。

在本題中也就是找到能夠與之相匹配的字符。然后,進(jìn)行交換,直至達(dá)到目標(biāo)要求。

題目分析:

首先分析Impossible 的兩種情況

n為奇數(shù)時(shí),如果已經(jīng)有一個(gè)字符出現(xiàn)的次數(shù)為奇數(shù),還找到了一個(gè)字符出現(xiàn)的次數(shù)為奇數(shù),那么就不能構(gòu)成回文串。

n為偶數(shù)時(shí),只要找到有一個(gè)字符出現(xiàn)的次數(shù)為奇數(shù),那么就不能構(gòu)成回文串。

還有一個(gè)就是題目所說(shuō)的最小的交換次數(shù)

如果 n 為偶數(shù),那么從第一字符開(kāi)始,從后往前找第一個(gè)和它相同的字符,如果找了,就將找到的字符交換到最后一個(gè)位置,在下一次遍歷時(shí),就可以不用管剛才已經(jīng)交換好的那來(lái)兩個(gè)字符,下一次從第二個(gè)字符開(kāi)始,從倒數(shù)第二個(gè)字符開(kāi)始遍歷,執(zhí)行和上述相同的操作。

如果 n 為奇數(shù),在字符串的某一個(gè)位置找到了那個(gè)出現(xiàn)次數(shù)為奇數(shù)的字符,我們不必將次字符現(xiàn)在就交換到中間位置,而是先計(jì)算它到中間位置需要交換的次數(shù),然后累加到 count 中,將剩下的字符都交換到對(duì)稱(chēng)后,再交換這個(gè)字符即可。

這是因?yàn)槿绻哑鏀?shù)移動(dòng)到中間,假設(shè)有一對(duì)數(shù)都在以中間為界限的左邊或者都在右邊的話(huà),那么交換成回文的時(shí)候就一定要經(jīng)過(guò)中間,這就會(huì)造成count多增加了一次,這是不必要的,因?yàn)榭梢运械幕匚囊苿?dòng)完了之后再把這個(gè)獨(dú)立的奇數(shù)移動(dòng)過(guò)去,不僅能達(dá)到同樣的效果還能保證交換次數(shù)最少。

例如:

有這么幾個(gè)數(shù)

b d c c f f b

我們不考慮第二個(gè)奇數(shù)直接交換第三個(gè)數(shù),這樣只需要1步,但是當(dāng)你把第二個(gè)奇數(shù)交換到中間之后就會(huì)有如下結(jié)果

b c c d f f b

可以了解一下 φ(>ω

代碼:

#include

#include

using namespace std;

int main() {

int n;

cin >> n;

string s;

cin >> s;

int end = n - 1;//字符串最后一個(gè)字符

int count = 0;//交換次數(shù)

int OddNum = 0;//判斷是否已經(jīng)有一個(gè)單獨(dú)的奇?zhèn)€數(shù)的字符了

for (int i = 0; i < end; ++i) {//從第一個(gè)字符到倒數(shù)第二個(gè)字符遍歷

for (int j = end; j >= i; --j) {//從最后一個(gè)開(kāi)始,到第i個(gè)字符,尋找與s[i]相同的字符

if (i == j) {//如果沒(méi)找到

if (n % 2 == 0 || OddNum == 1) { //不可能的兩種情況

cout << "Impossible" << endl;

return 0;

}

OddNum = 1;//找到一個(gè)字符出現(xiàn)的次數(shù)為奇數(shù)

count += n / 2 - i;//將次字符交換到中間位置的次數(shù)

}

else if (s[i] == s[j]) {//如果找到了,將s[j]交換到s[end]位置

for (int k = j; k < end; ++k) {

swap(s[k], s[k + 1]);//交換相鄰兩個(gè)位置的字符

++count;

}

--end;//末尾遞減

break; //開(kāi)始從i+1處重復(fù)操作

}

}

}

cout << count << endl;

system("pause");

return 0;

}

對(duì)于我:

但是在這里我還發(fā)現(xiàn)我有一個(gè)基礎(chǔ)知識(shí)點(diǎn)薄弱的地方那就是多個(gè)if跟if··· if else 的區(qū)別

if (條件){語(yǔ)句}

這種格式中,程序會(huì)依次判斷條件1和條件2是否成立并根據(jù)結(jié)果決定是否執(zhí)行語(yǔ)句1和語(yǔ)句2,也就是說(shuō),第一個(gè) if 塊和第二個(gè) if 塊沒(méi)有影響(除非在執(zhí)行第一個(gè) if 塊的時(shí)候就兇殘地 return 了)

而下面這種格式,

if (條件){}

else if(條件){}

f 塊和 else if 塊本質(zhì)上是互斥的!也就是說(shuō),一旦語(yǔ)句1得到了執(zhí)行,程序會(huì)跳過(guò) else if 塊,else if 塊中的判斷語(yǔ)句以及語(yǔ)句2一定會(huì)被跳過(guò);同時(shí)語(yǔ)句2的執(zhí)行也暗含了條件1判斷失敗和語(yǔ)句1沒(méi)有執(zhí)行;當(dāng)然還有第3個(gè)情況,就是條件1和條件2都判斷失敗,語(yǔ)句1和語(yǔ)句2都沒(méi)有得到執(zhí)行。

總結(jié)

以上是生活随笔為你收集整理的完美的代价 c语言,蓝桥杯基础练习 完美的代价的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。