算法讨论
仔细观察一下,给出这个 s s s无所谓,其实统计下没个字母的个数即可,然后就是看如何构造了,可以看到就是 0 0 0必然是最大的那个,然后根据 0 0 0可以找到第二大的字母的所有位置,接着再找第三大的,我刚开始走了误区,我以为把这个 s u m sum sum排个序,然后从前到后统计统计,之后发现有很大问题,不如就像个集合那样,一个一个扩展进去,最多也就是 n 3 n^3 n3的算法,之后就简单了,直接统计第几大的字母个数,然后打上对应的字母即可。
算法实现
const int N=30;
string s;
int n,cnt[N];
struct data{
int sum,id,pre;
string s;
}v[55];
bool cmp2(data a,data b){return a.pre<b.pre;}
bool cmp3(data a,data b){return a.id<b.id;}
int main()
{
rush(){
cin>>s;
rep(i,0,25)cnt[i]=0;
rep(i,0,s.size()-1)cnt[s[i]-'a']++;
cin>>n;
for(int i=0;i<n;v[i].id=i,i++)cin>>v[i].sum;
int ini=-1;
while(233){
for(int i=ini+1;i<n;i++){
bool sus=false;
if(v[i].sum==0)swap(v[i],v[++ini]),v[ini].pre=0;
else{
int tmp=0;
for(int j=0;j<=ini;j++){
tmp+=abs(v[j].id-v[i].id);
if(tmp==v[i].sum){
swap(v[++ini],v[i]);
v[ini].pre=j+1;
sus=true;
break;
}
}
}
if(sus)break;
}
if(ini==n-1)break;
}
sort(v,v+n,cmp2);
int q=-1,tot=25;
v[n].pre=-1;
rep(i,0,n-1){
if(v[i].pre==v[i+1].pre)continue;
else{
int len=i-q;
while(cnt[tot]<len)tot--;
per(j,i,q+1)v[j].s=tot+'a';
tot--;
q=i;
}
}
sort(v,v+n,cmp3);
rep(i,0,n-1)cout<<v[i].s;
cout<<endl;
}
return 0;
}