escape

首先题目要求最后字典序最小的,而且只包含小写字母,因此显而易见像$a$,$b$这样的字符越在前面越好。

考虑贪心。

枚举这个字符串的每一个位置,然后再枚举小写字母$a$ ~ $z$,能换则换,就是尽量将字典序最小的换到最前面,或者退而求其次。

$code$:

 1 #include <bits/stdc++.h>
 2 #define INF 0x3f3f3f3f
 3 #define ll long long
 4 using namespace std;
 5 char s[1010];
 6 int n, cnt[150], dic[150][1010], num[1010];
 7 ll k;
 8 int main()
 9 {
10 //    freopen("escape.in", "r", stdin), freopen("escape.out", "w", stdout);
11     scanf("%d %lld %s", &n, &k, s + 1);
12     for(int i = n; i >= 1; --i) dic[s[i]][++cnt[s[i]]] = i, num[i] = cnt[s[i]];
13     for(int i = 1; i <= n; ++i)
14     {
15         if(!k) continue;
16         for(int ch = 'a'; ch <= 'z'; ++ch)
17         {
18             if(cnt[ch] && dic[ch][cnt[ch]] - i <= k)
19             {
20                 if(dic[ch][cnt[ch]] == i) break;//这块没加就挂……
21                 k -= (dic[ch][cnt[ch]] - i); --cnt[ch];
22                 int ddd, dd = num[i + 1]; char c, t = s[i + 1]; s[i + 1] = s[i]; s[i] = ch; ++dic[s[i + 1]][num[i]]; num[i + 1] = num[i];
23                 for(int j = i + 1; j < dic[ch][cnt[ch] + 1]; ++j) c = s[j + 1], s[j + 1] = t, t = c, ++dic[s[j + 1]][dd], ddd = num[j + 1], num[j + 1] = dd, dd = ddd;
24                 break;
25             }
26         }
27     }
28     for(int i = 1; i <= n; ++i) printf("%c", s[i]);
29     return 0;
30 }

 

posted @ 2020-10-03 14:48  louis_11  阅读(138)  评论(0编辑  收藏  举报