Codeforces Round #650 (Div. 3) D. Task On The Board (构造,贪心)

Posted lr599909928

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #650 (Div. 3) D. Task On The Board (构造,贪心)相关的知识,希望对你有一定的参考价值。

技术图片

  • 题意:有一个字符串和一组数,可以对字符串删去任意字符后为数组的长度,且可以随意排序,要求修改后的字符串的每个位置上的字符满足:其余大于它的字符的位置减去当前位置绝对值之和等于对应序列位置上的数.

  • 题解:贪心,我们发现,数组中(0)的位置一定对应字符串中最大的字符,所以我们从这个位置来构造,我循环来找,每次找数组中为(0)的位置,然后记录字符,对其他没有取过的位置减去为(0)的位置,每次都这样搞就行了.具体的还是看代码吧,每一步都应该听清晰的.

  • 代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <stack>
    #include <queue>
    #include <vector>
    #include <map>
    #include <set>
    #include <unordered_set>
    #include <unordered_map>
    #define ll long long
    #define fi first
    #define se second
    #define pb push_back
    #define me memset
    const int N = 1e6 + 10;
    const int mod = 1e9 + 7;
    const int INF = 0x3f3f3f3f;
    using namespace std;
    typedef pair<int,int> PII;
    typedef pair<ll,ll> PLL;
    
    int t;
    string s;
    int n;
    int a[N];
    bool vis[N];
    char res[N];
    map<char,int> mp;
    
    int main() {
        ios::sync_with_stdio(false);cin.tie(0);
        cin>>t;
        while(t--){
            cin>>s;
            cin>>n;
            me(vis,0,sizeof(vis));
            me(res,‘0‘,sizeof(res));
            mp.clear();
    
            for(int i=1;i<=n;++i){
                cin>>a[i];
            }
            for(int i=0;i<s.size();++i){
                mp[s[i]]++;
            }
    
            char k=‘z‘+1;
            int sum=0;
            int cnt=0;
            while(sum!=n){
                cnt=0;
                for(int i=1;i<=n;++i){          //find 0
                    if(a[i]==0 && !vis[i]){
                        cnt++;
                    }
                }
                for(auto i=k-1;i>=‘a‘;--i){     //找当前最大的字符
                    if(mp[i]>=cnt){
                        k=i;
                        break;
                    }
                }
                for(int i=1;i<=n;++i){          //找等于0位置
                    if(a[i]==0 && !vis[i]){
                        sum++;
                        vis[i]=true;
                        res[i]=k;
                    }
                }
                for(int i=1;i<=n;++i){           //对其他没有取过的位置求贡献
                    if(a[i]==0 && res[i]==k){
                        for(int j=1;j<=n;++j){
                            if(a[j]>0)
                                a[j]-=abs(j-i);
                        }
                    }
                }
            }
            for(int i=1;i<=n;++i){
                cout<<res[i];
            }
            cout<<‘
    ‘;
        }
    
        return 0;
    }
    
    

以上是关于Codeforces Round #650 (Div. 3) D. Task On The Board (构造,贪心)的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #650 (Div. 3) A. Short Substrings

Codeforces Round #650 (Div. 3) C. Social Distance

Codeforces Round #650 (Div. 3) C. Social Distance (前缀和)

Codeforces Round #436 E. Fire(背包dp+输出路径)

Codeforces Round #650 (Div. 3) E. Necklace Assembly (暴力)

Codeforces Round #650 (Div. 3) D : Task On The Board