考 虑 b i = 0 的 特 殊 点 考虑b_i=0的特殊点 bi=0

b i = 0 的 点 一 定 是 当 前 字 母 最 大 的 , 否 则 会 和 更 大 的 字 母 产 生 贡 献 b_i=0的点一定是当前字母最大的,否则会和更大的字母产生贡献 bi=0,

所 以 第 一 步 , 用 最 大 且 足 够 数 目 的 字 母 去 填 充 所 有 b i = 0 , 标 记 填 过 所以第一步,用最大且足够数目的字母去填充所有b_i=0,标记填过 ,bi=0,

那 么 其 余 没 填 过 的 都 比 这 些 字 母 小 , 所 以 对 其 余 的 b i 修 改 那么其余没填过的都比这些字母小,所以对其余的b_i修改 ,bi

怎 么 修 改 ? 比 如 b i = 0 且 没 被 标 记 的 点 位 置 是 n u m 怎么修改?比如b_i=0且没被标记的点位置是num ?bi=0num

那 么 对 于 所 有 的 b j ! = 0 , b j = b j − a b s ( n u m − j ) , 也 就 是 减 掉 n u m 对 j 的 影 响 那么对于所有的b_j!=0,b_j=b_j-abs(num-j),也就是减掉num对j的影响 bj!=0,bj=bjabs(numj),numj

修 改 后 , 又 有 一 些 没 标 记 的 b i 变 成 0 , 那 么 这 些 点 是 余 下 点 中 最 大 的 修改后,又有一些没标记的b_i变成0,那么这些点是余下点中最大的 ,bi0,

重 复 上 面 的 步 骤 即 可 完 成 步 骤 重复上面的步骤即可完成步骤

#include <bits/stdc++.h>
using namespace std;
const int maxn=1299;
char a[maxn],ans[maxn];
int shu[27],vis[maxn],m,b[maxn];
int main()
{
	int t,n;
	cin>>t;
	while(t--)
	{
		memset(shu,0,sizeof(shu));
		cin>>(a+1)>>m;
		for(int i=1;i<=m;i++)	cin>>b[i];
		for(int i=1;i<=strlen(a+1);i++)
			shu[a[i]-'a'+1]++;
		int num=26,da=0;
		while(1)
		{
			int zero=0,k;
			for(int i=1;i<=m;i++)
				if(b[i]==0&&vis[i]==0)	zero++;
			for(int i=num;i>=1;i--)
				if(shu[i]>=zero)
					{ k=i;break;}
			int cc=0,he=0;
			for(int i=1;i<=m;i++)
			{
				if(b[i]==0&&vis[i]==0)//当前最大的字母 
				{
					vis[i]=1;da++;
					ans[i]=char(k+'a'-1);
					for(int j=1;j<i;j++)
						if(b[j])	b[j]-=(i-j);//减去i字母后面的影响 
					cc++,he+=i;
				}
				else if(b[i])
					b[i]=b[i]-(cc*i-he);//减去i字母前面的影响 
			}
			num=k-1;//找下一个字母 
			if(da==m)	break;
		}
		for(int i=1;i<=m;i++)	cout<<ans[i];
		cout<<endl;
		for(int i=1;i<=m;i++)	vis[i]=0;
	}
}