您的位置:首页 > 其它

(思维分析,贪心)湘大校赛,D.最小的数

2015-04-26 19:58 344 查看

最小的数

Accepted : 42Submit : 255
Time Limit : 1000 MSMemory 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐