一看就会——蓝桥杯 试题 基础练习 完美的代价——贪心法,21行代码AC
貪心算法的定義:
貪心算法是指在對問題求解時,總是做出在當前看來是最好的選擇。也就是說,不從整體最優上加以考慮,只做出在某種意義上的局部最優解。貪心算法不是對所有問題都能得到整體最優解,關鍵是貪心策略的選擇,選擇的貪心策略必須具備無后效性,即某個狀態以前的過程不會影響以后的狀態,只與當前狀態有關。
貪心在本題的應用:
對于本題,應用貪心算法的思路就是:每次改動,都確保離標準的答案更近了一步。 比如: aabbm串, 經過一步(一步中可能含有若干操作)貪心后,變為:abbma,則認為這次貪心是成功的。
思路:
1、本題的規則是:每個字符只能與相鄰的字符交換。(最開始以為可以跳躍交換,搞了半天才發現看錯了。哭o(╥﹏╥)o)
2、最開始的思路:
遍歷前半個串每個字符, 如果該字符對立面不等于它, 則繼續遍歷,找到相等的字符放到對立面,num增加對應的步數。
如果沒找到某個字符 且為串中值個數為偶,就失敗, 如果沒找到且為奇,則判斷是否是第一次出現這種情況,若是,則將這個字符放到串中間。若不是,則失敗。最后輸出num(因為一個回文串中不可能有兩個及以上出現過一次的字符)。
但在調試的過程中,發現了一個bug,如果很早的發現了某個字符在串中只有一個,并且移動到了串中間,但其他字符在匹配移動的過程中,會導致這個字符移位。
如:ffdejjell,第一步貪心肯定是將第二個f移到最后一個,就變成了:fdejjellf。但當遍歷到d時,按照原來的思路,需要把它放在中間。像這樣:fejjdellf。但當我們后續遍歷j的位置時,由于需要一個一個挪動,就會導致d不在中間了,原來的操作就白做了。
解決的辦法是:d放在原位不動,后續遍歷的字符都要與他們對稱位的后一位匹配。 如:fdejjllef中,e就是匹配的。全部遍歷完后,就變成了:fdejlljef,最后將d移動三次,變成:fejldljef。完成。
代碼:
#include<iostream> using namespace std; int main() {int i, j, n, ans=0, flag = 0;string a;cin >> n >> a;for(i = 0; i < n; i++) { //i從前往后遍歷 for(j = n-1; j >= i; j--) { //j從后往前遍歷 if(i == j) { //如果沒找到可以匹配的。 if(a.size()%2==0 || flag==1) { cout <<"Impossible"; return 0; }flag++; ans+= a.size()/2-i;} else if(a[i]==a[j]) { //如果找到了。 for(int k = j; k < (n-1); k++)swap(a[k], a[k+1]);ans += n-1-j;n--; break; //break一定放在所有語句后面。反之則它后面的語句全部失效。}}} cout << ans; return 0; }總結
以上是生活随笔為你收集整理的一看就会——蓝桥杯 试题 基础练习 完美的代价——贪心法,21行代码AC的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何快速理解递归——看这个就可以了
- 下一篇: 解题报告+优化——试题 基础练习 矩形面