题意:帮助Jeff去改良她产品的名字,使得她产品名字的字典序小于她的对手。
给出字符串s,表示Jeff的产品名字,给出字符串c,表示她竞争对手的产品名字,找出一种方式,至多交换一对s中的字符,使得Jeff的产品名字字典序严格小于她的竞争对手。
字典序严格小于的定义:对于字符串a和字符串b
只要满足如下一个,字符串a的字典序严格小于b
1.a是b的一个前缀,且a 不等于 b
2.存在一个整数1 <= i <= min(|a|, |b|),ai < bi,还有aj = bj(1 <= j < i)
//第二个条件的意思是说a和b的前j个字符相等,但是第i个字符 ai < bi
输入
t:t组数据(1 <= t <= 1500)
每组数据包含两个字符串s和c(2 <= |s| <= 5000,1 <= |c| <= 5000),字符串s和字符串c由大写字符组成。
分析:我们可以从前往后遍历s,在当前字符的时候,寻找后面是否存在比当前字符小的字符,并且是最小的,使得交换后的字符串字典序小于c。//如果不存在的话,说明该字符后面的字符都小于当前字符,
说明这个位置是个无法变小的位置,因此我们在继续后面的遍历,如果后面存在比当前字符小的字符,那么就交换,为什么交换后就break循环呢?因为如果当前字符交换完,那么遍历到后面的字符时,即使交换了,也不会比这次交换,带来的字符串更小,所以一旦第一次出现可以交换的现象,就break。
并且如果后面存在多个可以交换的字符(即最小的且相等的)那么我们就交换最后一个,因为这样就会把当前字符放在很后面。
#include <iostream>
#include <string>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int main()
{
int t;
scanf("%d", &t);
string s, c;
while (t--)
{
cin >> s >> c;
for (int i = 0; i < (int)s.length(); ++i)
{
int pos = i;
for (int j = s.length() - 1; j >= i; --j)
{
//寻找后面一个最小的字符
if (s[j] < s[pos]) pos = j;
}
if (pos != i)
{
swap(s[pos], s[i]);
break;
}
}
if (s < c)
cout << s << endl;
else
cout << "---" << endl;
}
return 0;
}