题目大意:
对于一个字符串t,给定b数组的定义:对于第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
**/