中石油 4509 keks(贪心)

传送门:点击打开链接

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;
				else
					break;
			}			
		}

		flag[j]=0;
	}

	for(i=0;i<n;i++){
		if(flag[i]==1)
			printf("%d",a[i]);
	}

	putchar('\n');
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值