中石油 4509 keks(贪心)

来源:互联网 发布:百度地图经纬度数据库 编辑:程序博客网 时间:2024/05/18 01:21

传送门:点击打开链接

4509: keks

时间限制: 1 Sec  内存限制: 128 MB
提交: 19  解决: 4
[提交][状态][讨论版]

题目描述

给出一个n位数,要求删掉其中k位数字,使得剩下的数字组成的数尽量大。

输入

第1行:两个正整数n, k(1 <= k < n <= 500,000)。
第2行:一个n位正整数(无前导0)。

输出

输出一行,一个正整数,表示剩下的数的最大值。

样例输入

4 2
1924

样例输出

94

不难发现,这就是一个跑下标的问题,贪心,把递增序列的前几项删除,当递减序列跟递增序列交替时,形成类似山谷的形状,只需要设定两个坐标,一个扫递减序列,一个扫递增数列,删除两者中较小的那一个,删除用数组标记,如果扫完数组后k值没达到,此时剩下的序列一定会是递减的,只需要从最后一位往前扫就可以了,删除到第k个数时,跳出循环,结束。

还有一个领导出的每次删最小数值的,也贴上代码。


代码实现:

#include<iostream>#include<algorithm>#include<cstring>#include<cmath>#include<queue>#include<cstdio>#define ll long long#define mset(a,x) memset(a,x,sizeof(a))using namespace std;const double PI=acos(-1);const int inf=0x3f3f3f3f;const double esp=1e-6;const int maxn=5e5+5;const int mod=1e9+7;int dir[4][2]={0,1,1,0,0,-1,-1,0};char map[maxn];int visit[maxn];int main(){int n,k,i,j;while(cin>>n>>k){getchar();cin>>map;mset(visit,1);int l=0,r=1;while(r<n&&k){while(l>=0&&k&&map[l]<map[r]){k--;visit[l]=0;while(l>=0&&!visit[l])l--;}l=r;r++;}r=n-1;while(k&&r>=0){if(visit[r]){visit[r]=0;k--;}r--;}for(i=0;i<n;i++){if(visit[i])cout<<map[i];}cout<<endl;}return 0;}


#include <stdio.h>#include <math.h>int main(){int num,temp,k;int n,m;int *a,*flag;int i,j,index;scanf("%d%d",&num,&k);n=log10(num)+1;a=new int[n];flag=new int [n];temp=num;for(i=0;i<n;i++){flag[i]=1;a[n-1-i]=temp%10;temp/=10;}for(i=0;i<k;i++){j=0;while(flag[j]==0)j++;index=j;for(m=j+1;m<n;m++){if(flag[m]==1){if(a[m]>=a[j])j=m;elsebreak;}}flag[j]=0;}for(i=0;i<n;i++){if(flag[i]==1)printf("%d",a[i]);}putchar('\n');return 0;}


原创粉丝点击