178543 4 1000001 1 100001 2 12345 2 54321 2
13 1 0 123 321
题意:给你一个数字串,要你删除m个数字后所得的最小数字串是多少。
分析:本题是搜RMQ-ST算法题目搜到的。但是没想到怎么用它来做。然后本题其实可以直接贪心过的。但是首先要想清楚一些问题。
删除m个数字,相当于在里面从左往右取n-m个数字;所得数最小,也就是每次取得数字尽量小。那么,取得的第一个数字一定在区间[0,m]内,为什么呢?因为除了第一个数之外还要取n-m-1个数字,所以区间右边界最大只能是m,每次在区间里找最小的那个数(尽量靠左);依次类推,假设第一个数字取得的下标是index1,那么,第二个数字一定是在[index1+1,m+1]内取得;依次类推下去,右边界每次加1。当选取到了n-m个数字之后,也就找到了答案了~
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3183
代码清单:
#include<set>
#include<map>
#include<cmath>
#include<queue>
#include<stack>
#include<ctime>
#include<string>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
const int maxn = 1e3 + 5;
int m,l,r,k;
char s[maxn];
char ans[maxn];
int main(){
while(scanf("%s %d",s,&m)!=EOF){
l=0; r=m; k=0;
m=strlen(s)-m;
while(m--){
int index=l;
for(int i=l;i<=r;i++){
if(s[index]>s[i]) index=i; //注意是>,而不是>=
}
ans[k++]=s[index];
l=index+1;
r++;
}
int head=0;
while(ans[head]=='0'&&head<k) head++; //去掉前导0
if(head==k) printf("0\n");
else{
for(;head<k;head++) printf("%c",ans[head]);
printf("\n");
}
}return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/jhgkjhg_ugtdk77/article/details/47306931