1611: PIPI当富豪(PIPIPOJ)
题目描述
PIPI的银行卡里有n位数,但是他不满足于此,PIPI想要让自己变得更富有,于是PIPI获得了1次修改银行卡数额的机会,但是他只能交换自己银行卡中数额的其中2位,PIPI想知道如何交换才能让自己变得最富有呢?
输入
第一行输入一个T表示有T组输入,1<=T<=10
接下来的T行,每行输入一个数,该数表示PIPI的银行卡里的数额,这个数额的位数为n,1<=n<=1e5
输出
对于每一个数,输出能使PIPI变得最富有的数额,每个数额之间用换行隔开
样例输入
7
44544
12345
54321
46587
78596
96191
78476
样例输出
54444
52341
54321
86547
98576
99161
87476
题解1(C++版本)
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
char s[N];
int t, n, R[N], L[N]; // R[i]表示从右往左i第一次出现的位置 ,L[i]表示从左往右i第一次出现的位置
int main(){
scanf("%d", &t);
while(t--){
memset(R, 0, sizeof R);
memset(L, 0, sizeof L);
scanf(" %s", s + 1);
n = strlen(s + 1);
for(int i = n; i > 0; i--) {
if(!R[s[i] - '0']) R[s[i] - '0'] = i;
}
for(int i = 1; i <= n; i++){
if(!L[s[i] - '0']) L[s[i] - '0'] = i;
}
for(int i = 9; i > 0; i--){
if(R[i]){
int mj = R[i];
// 寻找左边小于i的最小下标,并且返回的下标要>=1
for(int j = 0; j < i; j++){
if(!L[j]) continue;
mj = min(mj, L[j]);
}
if(mj != R[i]){
swap(s[R[i]], s[mj]);
break;
}
}
}
printf("%s\n", s + 1);
}
return 0;
}