最小的数 | ||
Accepted : 42 | Submit : 255 | |
Time Limit : 1000 MS | Memory Limit : 65536 KB |
题目描述给你一个n位数,每次操作可以选该数任意的相邻两位进行交换,如果最多可以操作k次,那么最终可以得到的最小的数是什么 (n位且不能含前导零)? 输入有多组测试数据,第一行为数据个数T(T<=10); 每组数据占一行,包含一个数(不超过1000位)和k(0<=k<=1000),中间用空格隔开; 输出最终能得到的最小的数。 样例输入2 321654987 1 321654987 2 样例输出231654987 132654987 |
/*
题意:如题。
分析:从最高位到最低位查看,尽可能的将可以取到的最小数“冒泡”到当前最高位。思路也属于一种贪心吧。
注意:当K次“冒泡”的机会没有使用完但处理到最低位时,剩余的机会就不使用了。
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn = 1005;
char s[maxn];
int K;
int num;
bool Find(int h, int l, int r,bool first)//注意最高位不能是“前导0”
{
bool flag = false;
char mark = s[h];
for (int i = l; i <= r; i++)
{
if (s[i]<s[h] && first?s[i] != '0':true)
{
if (s[i]<mark)
{
num = i;
mark = s[i];
flag = true;
}
}
}
return flag;
}
void Round(int en, int st)
{
for (int i = st; i != en; i--)
{
swap(s[i - 1], s[i]);
}
}
int main()
{
//freopen("input.txt","r",stdin);
int T;
scanf("%d", &T);
while (T--)
{
scanf("%s%d", s, &K);
int len = strlen(s);
int st = 0;
bool First = true;
for (; K; st++)
{
if (st == len - 1) break;
if (First)
{
if (Find(st, st + 1, min(st + K, len - 1),true))
{
K -= num - st;
Round(st, num);
}
First = false;
}
else
{
if (Find(st, st + 1, min(st + K, len - 1),false))
{
K -= num - st;
Round(st, num);
}
}
}
printf("%s\n", s);
}
return 0;
}