题目描述:
现在wanghang有一个字符串,这个字符串全部由大写字母组成,wanghang想知道由这个字符串的组成所有字母生成的由字典序从小到大的全排列是什么?
比如字符串是BCA,
那么全排列为:ABC,ACB,BAC,BCA,CAB,CBA
又比如字符串是ABB,
那么全排列为:ABB,BAB,BBA
jfs看到了这个问题,说:哈!太简单了!然后一下就给秒了!!!
wanghang表示不能忍,然后把问题改了下:如果修改了字母的优先级呢?
wanghang给出了每个字母的优先级,如果值越低表示优先级越高,如果值相同那么按照它们原本的字母顺序来确定优先级(A-Z由高到低)
如果P[x]表示当前字母x的优先级,
则字符串S的优先级大于字符串T当且仅当存在i使得P[S[i]]<P[T[i]]或(P[S[i]==P[T[i]]&&S[i]<T[i])
大致思路:
根据给出的优先级和原有字母排列顺序,可以得到一个新的字母表,从大到小的排列,然后将新得到的字母表与原有的字母表ABCD...XYZ进行一一映射,然后给出的字符串演变成了一个新的字符串,其字母优先级仍保持ABCD....XYZ不变,这样就可以直接对演变后的字符串进行next_p操作了~之后得到的字符串按新的字母表对应输出即可。
代码:
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
struct cn{
char c;
int p;
bool operator < (const cn &ano) const {
if (p==ano.p) return c<ano.c;
else return p<ano.p;
}
};
cn d[26];
int q,n,k;
char s[110];
int main() {
cin>>q;
while (q--) {
scanf("%s",s);
for (int i = 0; i<26; i++) {
d[i].c = i+'A';
scanf("%d",&d[i].p);
}
scanf("%d",&k);
sort(d,d+26);
char tmp[100]={""};
for (int i = 0; i<strlen(s); i++) {
for (int j = 0; j<26; j++) {
if (s[i]==d[j].c) {
tmp[i] = j+'A';
break;
}
}
}
for (int i = 0; i<strlen(tmp); i++) {
for (int j = i+1; j<strlen(tmp); j++) {
if (tmp[i]>tmp[j]) swap(tmp[i],tmp[j]);
}
}
for (int i = 0; i<strlen(tmp); i++) printf("%c",d[tmp[i]-'A'].c);
printf("\n");
while (--k) {
if (next_permutation(tmp,tmp+strlen(tmp))) {
for (int i = 0; i<strlen(tmp); i++) printf("%c",d[tmp[i]-'A'].c);
printf("\n");
}
else break;
}
}
}