codeforces 435 B. Pasha Maximizes 解题报告
題目鏈接:http://codeforces.com/problemset/problem/435/B
題目意思:給出一個最多為18位的數,可以通過對相鄰兩個數字進行交換,最多交換 k 次,問交換 k 次之后,這個數最大可以變成多少。
? ? ? 不知道最近是不是疏于訓練(一直研究百度之星的題目,最終決定就是暫時放下,可能能力還沒達到做那種題目的水平,不過都好感謝烏冬兄耐心甘為我解答左兩道題目),昨晚又想學學拓撲排序(SPFA提到),結果沒看明白= =...再加上昨晚比賽...電腦卡機卡得要命,于是悲催了= =
? ? ? 這個是賽后做的......做的時候不知道怎么在盡可能貪心和k次這個約束條件下取舍...看了別人的,一下子豁然開朗,晚上一打即過,哈哈哈....
? ? ? 大方向就是要往貪心的策略來想。怎樣貪心?當然是把位數越大的數字越往高位移動,這樣保證最終得到的數盡量大,但是,有一個關鍵的約束條件,就是不能超過 k 次,暗含的意思就是,裝載著數字比較大的位,移動到高位的距離不能超過 k 這個長度。?
? ? ? 以這組數據為例:
? ? ? 由于最高位的數字 9 是最大的,所以沒必要討論該位。那么從第二位數字0開始,后面的位中最大的那個數是第三位的9,將它與第二位數字交換,變成9900000078001234,次數從6變為5(因為交換了一次)....接著問題出現了,第三位的0究竟是拿最大的8(符合貪心的策略)不斷與前面的數交換,還是拿次小的7不斷與前面的數交換呢?如果是8,當交換5次之后,結果變成9900800007001234,而如果用7交換,結果變成9907000008001234,明顯是后面的數比較大。
? ? ? ?所以貪心不能亂貪,前提條件就是緊緊地遵循交換次數最多不能超過當前允許的次數。
? ? ?
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring> 5 #include <algorithm> 6 using namespace std; 7 8 const int maxn = 18 + 5; 9 char s[maxn]; 10 11 int main() 12 { 13 int k; 14 while (cin >> s >> k) 15 { 16 int len = strlen(s); 17 for (int i = 0; i < len; i++) 18 { 19 int t = i; // 討論第i位的數,后面有沒有更大的數可以替代它 20 for (int j = i+1; j < len && j-i <= k; j++) // j-i <= k就是滿足交換次數(實質就是j到i的距離)不能超過剩下最多能交換的次數k 21 { 22 if (s[j] > s[t]) 23 t = j; // 找出最大數的下標,前提是不超過k的次數 24 } 25 k -= (t-i); 26 while (t != i) // 代表找到比要討論的當前最高位要大的數 27 { 28 swap(s[t], s[t-1]); // 不斷向前交換 29 t--; 30 } 31 } 32 cout << s << endl; 33 } 34 return 0; 35 }?
? ? ??
轉載于:https://www.cnblogs.com/windysai/p/3762799.html
總結
以上是生活随笔為你收集整理的codeforces 435 B. Pasha Maximizes 解题报告的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: property_get 与 prope
- 下一篇: log4j.properties中的这句