CF1367D 构造

题意

给定一个字符串s,给定一个长度为m的数列b

要求从s中取出 m 个字符构成一个新的字符串a(不可重复取相同位置的字符),任意排列后,是其满足对于每一个 i 都有 a[i] 到 a 中 所有比它大的(即字典序比它大,如 b > a,z > x )的字符在字符串 a 中的距离之和为 b[i]

来源:洛谷

题解

首先题目保证有解

其次按照题目给定的定义来看,b中一定会有至少一个数字是0,因为在字符串s中一定存在这样一个字符是字典序最大的导致其他的字母没有办法与他坐距离定计算

那么根据这一条,我们根据字典序从后往前,对于每一个还没确定的位置,我们计算一下如果放在这个位置上她的距离符不符合b数组的距离,如果符合就可以放;

如果当前的字符满足b数组的个数在s中出现的次数不够,就尝试后几个能不能把这些满足的位置放满

(构造题我们要构造答案,题目保证答案有解)

Code

string s;
int n;
int b[150];
char t[150];

void solve(){
    memset(t, 0, sizeof(t));
    map<int, int> m;

    cin >> s;
    for(auto i : s){
        m[i]++;
    }
    cin >> n;
    for (int i = 1; i <= n; i++){
        cin >> b[i];
    }

    for (int c = 'z'; c >= 'a'; c--){
        vector<int> v;
        for (int i = 1; i <= n; i++){
            if(!t[i]){
                int summ = 0;
                for (int j = 1; j <= n; j++){
                    if(t[j]){
                        summ += abs(j - i);
                    }
                }
                if(b[i] == summ){
                    v.pb(i);
                }
            }
        }

        while(m[c] < v.size()){
            c--;
        }

        for(auto i : v){
            t[i] = c;
        }
    }
    for (int i = 1; i <= n; i++){
        cout << t[i];
    }
    cout << endl;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值