您的位置:首页 > 其它

2015 湘潭大学程序设计比赛(Internet)Problem D:最小的数

2015-04-26 20:38 323 查看


今天的比赛,因为时间问题,我就做了这一个题


题目描述

给你一个n位数,每次操作可以选该数任意的相邻两位进行交换,如果最多可以操作k次,那么最终可以得到的最小的数是什么

(n位且不能含前导零)?


输入

有多组测试数据,第一行为数据个数T(T<=10); 每组数据占一行,包含一个数(不超过1000位)和k(0<=k<=1000),中间用空格隔开;


输出

最终能得到的最小的数。


样例输入

2
321654987 1
321654987 2


样例输出

231654987 
132654987

这个题没有什么算法,就是用俩嵌套for循环,然后要注意一下边界条件就能A,比赛的时候WA了好几次,要么是忘了memset,要么ct忘了重置为0,要么就是j写成i,总之非常egg pain,犯了好多低级错误,不在状态啊。
我解释一下我的代码和思路把。
我这个类似于贪心算法,就是每次都把整个数列扫描一遍,用num[0~9]标记出0~9这10个数第一次出现的位置,然后从0开始往9for循环,如果最小的数的位置与当前要确定的位置距离小于等于k,那么就可以把这个数组挨个往后挪,然后把那个小的数放到当前操作的位置,k-=操作的距离。
我的代码还有好多需要完善的地方,能降低复杂度,但是比赛的时候比较匆忙,没顾上考虑这么多,能a就行。下面是我比赛的源代码。其实现在看有好多能剪枝的地方,如果这个算法超时,再改(我当时是这样想的)。

#include <iostream>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string>
#include <string.h>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <stack>
using namespace std;
typedef long long LL;
const int INF=0x7fffffff;
const int MAX_N=1009;
int T,k,ct;
char A[MAX_N];
int num[10];
int main(){
    cin>>T;
    while(T--){
        memset(A,0,sizeof(A));
        scanf("%s",A);
        scanf("%d",&k);
        int len=strlen(A);

        memset(num,-1,sizeof(num));
        ct=0;
        for(int i=1;i<len;i++){
            if(num[A[i]-'0']==-1){//这里也可以降复杂度,因为只要算小于A[0]的就行
                num[A[i]-'0']=i;
                ct++;
            }
            if(ct==10)break;
        }
        for(int i=1;i<=9;i++){//这个地方可以把9改成A[0]-'0'
            if(num[i]<=k&&num[i]!=-1&&i<A[0]-'0'){
                char cur=A[num[i]];
                for(int j=num[i];j>=1;j--){
                    A[j]=A[j-1];
                }
                A[0]=cur;
                k-=num[i];
                break;
            }
        }

        for(int i=1;i<len;i++){
            if(k==0)break;
            memset(num,-1,sizeof(num));
            ct=0;
            for(int j=i+1;j<len;j++){
                if(num[A[j]-'0']==-1){
                    num[A[j]-'0']=j;
                    ct++;
                }
                if(ct==10)break;
            }
            for(int j=0;j<=9;j++){
                if(num[j]-i<=k&&num[j]!=-1&&j<A[i]-'0'){
                    char cur=A[num[j]];
                    for(int p=num[j];p>i;p--){
                        A[p]=A[p-1];
                    }
                    A[i]=cur;
                    k-=num[j]-i;
                    break;
                }
            }
        }

        cout<<A<<endl;
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: