【Codeforces 1367D】 Task On The Board 思維+構造

題目大意:

對於一個字符串t,給定b數組的定義:對於第i個字符而言:bi = \sum_{j=1}^{j=len}{|j-i|,t_j>t_i}

給出一個字符串s,字符串t的長度及字符串的t的b數組

要求夠造出一個字符串t,使得滿足b數組及長度並且該字符串的所有字符及其數量均在s內

題目思路:

一週沒寫代碼菜的連d3的D都不會.

首先肯定確定的是,當bi爲0時絕對是最大的那個字母

根據這個性質出發,考慮能否確定第二大字母?(因爲這樣就可以百分百確定一位字母)

可以這麼想,首先bi = 0的字母賦值,賦值之後取消這個字母對剩下字母的影響。

那麼此時必定會有新的bi = 0,而此時因爲取消了最大字母的影響,所以這個bi = 0就是第二大的字母的所有位置了

所以注意以下幾點就可以了

1.從大到小遍歷:保證之前的不會對之後的產生影響

2.取消這個字母時的影響時,取消的是新增爲0字母的影響

3.討論可不可以放某一個字母時還需要考慮其次數是否大於需要的位置次數

Code:

/*** keep hungry and calm CoolGuang!***/
#include <bits/stdc++.h>
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast","unroll-loops","omit-frame-pointer","inline")
#include<stdio.h>
#include<queue>
#include<algorithm>
#include<string.h>
#include<iostream>
#define debug(x) cout<<#x<<":"<<x<<endl;
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const ll INF=1e16;
const int maxn=2e6+6;
const int mod=1e6+6;
const double eps=1e-15;
inline bool read(ll &num)
{char in;bool IsN=false;
    in=getchar();if(in==EOF) return false;while(in!='-'&&(in<'0'||in>'9')) in=getchar();if(in=='-'){ IsN=true;num=0;}else num=in-'0';while(in=getchar(),in>='0'&&in<='9'){num*=10,num+=in-'0';}if(IsN) num=-num;return true;}
ll n,m,p;
char s[maxn],t[maxn];
int c[30],vis[maxn];
ll num[maxn];
char res[maxn];
int main(){
    int T;scanf("%d",&T);
    while(T--){
        scanf("%s",s+1);
        n = strlen(s+1);

        memset(c,0,sizeof(c));
        memset(vis,0,sizeof(vis));

        for(int i=1;i<=n;i++) c[s[i]-'a'] ++;

        read(m);
        for(int i=1;i<=m;i++) read(num[i]);

        int s = 25;

        while(1){
            vector<int>v,g;
            for(int i=1;i<=m;i++){
                if(!num[i]){
                    if(vis[i]) continue;
                    v.push_back(i);
                }
                else g.push_back(i);
            }
            int f = 0;
            if(!g.size()) f = 1;
            int sz = v.size();
            while(c[s]<sz) s--;
           // debug(s);
            for(int tempx:g){
                ll ans = 0;
                for(int tempy:v)
                    ans += abs(tempx-tempy);
                num[tempx] -= ans;
            }
            for(int e:v){
                vis[e] = 1;
                res[e] = s+'a';
            }
            s--;
            if(f) break;
        }
        for(int i=1;i<=m;i++) printf("%c",res[i]);
        printf("\n");
    }
    return 0;
}
/**

abac
2 1 0
    c
0 0 c
**/

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章