C. K-beautiful Strings(字符串+贪心+暴力)

题目链接:https://codeforces.ml/contest/1493/standings/friends/true

题解:参考issue敲腻害

我的困惑:sum>i时怎么处理。

解决方法,取a[i]本身肯定不行,就枚举a[i]+1~26,第一个字母大就一定满足(前提是能配齐),配不够的全换成a即可。

玛德。真的会有那么一道题,让你不想搞acm。我能做的,保持好心态即可。

总结:

(1)几乎每道题的解法思路,一定是超级简单易懂的。如果自己都不确定自己能否实现自己的想法,那就及时改变思路。

永远不要轻易将一道题想的很难!因为绝大多数题都不配!!!

(2)暴力大法好!!!

代码:

#include <bits/stdc++.h>

#define ll long long
#define pi acos(-1)
#define pb push_back
#define mst(a, i) memset(a, i, sizeof(a))
#define pll pair<ll, ll>
#define fi first
#define se second
#define mp(x, y) make_pair(x, y)
#define rep(i, a, n) for (ll i = a; i <= n; i++)
#define per(i, n, a) for (ll i = n; i >= a; i--)
#define dbg(x) cout << #x << "===" << x << endl
#define dbgg(l, r, x)                                \
    for (ll i = l; i <= r; i++) cout << x[i] << " "; \
    cout << "<<<" << #x << "\n"
//多动脑,少动笔
using namespace std;

template <class T>
void read(T &x) {
    T res = 0, f = 1;
    char c = getchar();
    while (!isdigit(c)) {
        if (c == '-') f = -1;
        c = getchar();
    }
    while (isdigit(c)) res = (res << 3) + (res << 1) + c - '0', c = getchar();
    x = res * f;
}
void Printf(ll x) {
    if (x < 0) putchar('-'), x = -x;
    if (x > 9) Printf(x / 10);
    putchar(x % 10 + '0');
}
void print(ll x, char c) { Printf(x), putchar(c); }
const ll maxn = 1e5 + 10;
const ll mod = 1e9 + 7;
const ll inf = 1e9;

ll n, k;
ll a[maxn];
ll cnt[30], b[30];
char s[maxn];
ll sum, y;
void init() {
    rep(i, 1, 26) cnt[i] = b[i] = 0;
    sum = y = 0;
}
void PPrint(ll l, ll x) {
    rep(i, 1, l - 1) putchar(a[i] + 'a' - 1);
    if (l <= n) putchar(x + 'a' - 1);
    rep(i, 1, 26) {
        rep(j, 1, b[i]) { putchar(i + 'a' - 1); }
    }
    puts("");
}
int main() {
    // freopen("testdata.in","r",stdin);
    // freopen("testout.out","w",stdout);
    ll TT = 1;
    read(TT);
    while (TT--) {
        init();
        read(n), read(k);
        scanf("%s", s + 1);
        if (n % k) {
            puts("-1");
            continue;
        }
        rep(i, 1, n) {
            a[i] = s[i] - 'a' + 1;
            cnt[a[i]]++;
        }
        rep(i, 1, 26) {
            b[i] = (k - cnt[i] % k) % k;
            sum += b[i];
        }
        bool f = false;
        // dbg(sum);
        if (sum == 0) {
            f = true;
            PPrint(n + 1, 1);
        }
        per(i, n, 1) {
            if (f) break;
            //看前i-1是什么情况。
            y = n - i + 1;
            ll r = b[a[i]];
            b[a[i]] = (b[a[i]] + 1 + k) % k;
            sum -= (r - b[a[i]]);
            // cout << ">>>>" << i << ' ' << sum << endl;

            if (y < sum)
                continue;
            else {
                rep(j, a[i] + 1, 26) {
                    if (y == sum && b[j] == 0) continue;
                    r = b[j];
                    b[j] = (b[j] - 1 + k) % k;
                    sum -= (r - b[j]);
                    b[1] += y - 1 - sum;
                    PPrint(i, j);
                    f = true;
                    break;
                }
            }
        }
        // if(!f) puts("-1");
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值