题目链接:
http://acm.nyist.net/JudgeOnline/problem.php?pid=1057
描述
给出一个整数N,每次可以移动2个相邻数位上的数字,最多移动K次,得到一个新的整数。
求这个新的整数的最大值是多少。
输入
多组测试数据。
每组测试数据占一行,每行有两个数N和K (1 ≤ N≤ 10^18; 0 ≤ K ≤ 100)
输出
每组测试数据的输出占一行,输出移动后得到的新的整数的最大值。
样例输入
1990 1 100 0 9090000078001234 6 |
样例输出
9190 100 9907000008001234 |
算法思想:
贪心算法,每次选取当前最高位最大的,选取范围在num~num + k之间,其中num代表已经前面已经选好的下一个位置,k为还可能移动的次数。选取好之后,移动该元素到当前最高位,更新num++,更新k。直到k为0或者num = str.length()了,也就是没有移动次数了或者已经所有数字已经排好序了,不能在移动更改了。
源代码
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
string str;
//在start至end之间,寻找最大的字符数字,返回其位置
int getMax(int start, int end)
{
int pos = start;
char ch = str[start];
for (int i = start; i <= end; i++)
{
if (str[i] > ch)
{
ch = str[i];
pos = i;
}
}
return pos;
}
int main()
{
int k, len, pos, num;//k为输入的移动次数,len为输入字符串的长度,pos位置标记,num为当前最高位(出去已排好的最高位)
while (cin >> str >> k)
{
num = 0;
len = str.length();
while (k)
{
//当num + k小于len,则在num和num + k之间寻找最大值
if (num + k < len)
{
pos = getMax(num, num + k);
}
//当num + k >= len且num < len - 1,则在num和len之间寻找最大值,以防越界。
else if (num < len - 1)
{
pos = getMax(num, len);
}
//当num >= len - 1,说明已经寻找到最低位了,不用移动任何数据了,跳出循环
else
{
break;
}
//当pos != num时,移动相邻字符,直到将最大值移到当前最高位,
while (pos != num)
{
//移动相邻位,交换
swap(str[pos - 1], str[pos]);
//更新pos和k
pos--;
k--;
}
num++;
}
cout << str << endl;
}
return 0;
}