传送门:点击打开链接
4509: keks
时间限制: 1 Sec 内存限制: 128 MB提交: 19 解决: 4
[ 提交][ 状态][ 讨论版]
题目描述
给出一个n位数,要求删掉其中k位数字,使得剩下的数字组成的数尽量大。
输入
第1行:两个正整数n, k(1 <= k < n <= 500,000)。
第2行:一个n位正整数(无前导0)。
第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;
else
break;
}
}
flag[j]=0;
}
for(i=0;i<n;i++){
if(flag[i]==1)
printf("%d",a[i]);
}
putchar('\n');
return 0;
}