题目链接
题意:
给你一个字符串s,你可以将该字符串删掉任意字符(也可以不删),然后再任意排序组成一个字符串,组成之后的字符串t[i]有一个数组b[i]表示t[i]与t中其他比t[i]字典序大的字符索引j的 |i - j| 的和,给你s,t[i]的长度和b[i],求t[i]。
思路:
首先找b[i]中的0,因为0肯定是最大的字母,然后减去0的字母对其他字母的影响,再在s中从大到小找满足0个数的字母补充t[i],然后再找0,再减去影响,再找字母,这样循环下去就能得到完整的t[i]。
代码:
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
const int N=2e5+7;
const int mod=998244353;
const int inf=0x7fffffff;
const double pi=3.1415926535;
using namespace std;
char a[N],t[N];
int b[N],vis[N],cnt[N];
signed main()
{
IOS;
int T;
cin>>T;
while(T--)
{
int m;
cin>>(a+1)>>m;
memset(cnt,0,sizeof cnt);
memset(vis,0,sizeof vis);
for(int i=1;i<=m;i++)
{
cin>>b[i];
}
int la=strlen(a+1);
for(int i=1;i<=la;i++)
{
cnt[a[i]-'a']++;
}
int ok=1,res=0,bg=25;
while(ok)
{
int num =0,tmp=-1;
for(int i=1;i<=m;i++)
{
if(!b[i]&&!vis[i])
{
num ++;
}
}
for(int i=bg;~i;i--)
{
if(cnt[i]>=num)
{
tmp=i;
break;
}
}
int tt=0,hh=0;
for(int i=1;i<=m;i++)
{
if(!b[i]&&!vis[i])
{
vis[i]=1;
res++;
t[i]= tmp + 'a';
for(int j=1;j<i;j++)
{
if(b[j])
{
b[j]-=(i-j);
}
}
hh+=i;
tt++;
}
else if(b[i])
{
b[i]-=(tt*i-hh);
}
}
bg=tmp-1;
if(res==m)
{
break;
}
}
for(int i=1;i<=m;i++)
{
cout<<t[i];
}
cout<<endl;
}
return 0;
}