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