题意
给定一个字符串s,给定一个长度为m的数列b
要求从s中取出 m 个字符构成一个新的字符串a(不可重复取相同位置的字符),任意排列后,是其满足对于每一个 i 都有 a[i] 到 a 中 所有比它大的(即字典序比它大,如 b > a,z > x )的字符在字符串 a 中的距离之和为 b[i]
来源:洛谷
题解
首先题目保证有解
其次按照题目给定的定义来看,b中一定会有至少一个数字是0,因为在字符串s中一定存在这样一个字符是字典序最大的导致其他的字母没有办法与他坐距离定计算
那么根据这一条,我们根据字典序从后往前,对于每一个还没确定的位置,我们计算一下如果放在这个位置上她的距离符不符合b数组的距离,如果符合就可以放;
如果当前的字符满足b数组的个数在s中出现的次数不够,就尝试后几个能不能把这些满足的位置放满
(构造题我们要构造答案,题目保证答案有解)
Code
string s;
int n;
int b[150];
char t[150];
void solve(){
memset(t, 0, sizeof(t));
map<int, int> m;
cin >> s;
for(auto i : s){
m[i]++;
}
cin >> n;
for (int i = 1; i <= n; i++){
cin >> b[i];
}
for (int c = 'z'; c >= 'a'; c--){
vector<int> v;
for (int i = 1; i <= n; i++){
if(!t[i]){
int summ = 0;
for (int j = 1; j <= n; j++){
if(t[j]){
summ += abs(j - i);
}
}
if(b[i] == summ){
v.pb(i);
}
}
}
while(m[c] < v.size()){
c--;
}
for(auto i : v){
t[i] = c;
}
}
for (int i = 1; i <= n; i++){
cout << t[i];
}
cout << endl;
}