D. Task On The Board(思维,构造)

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

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

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

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

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

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的影响

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

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

#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;
	}
}

猜你喜欢

转载自blog.csdn.net/jziwjxjd/article/details/106806356