P1106 删数问题

题目传送门|博客品尝更佳

这是一道非常经典的贪心题,还要用到高精字符串,要求追后剩下的最小的数,我们可以先来一个暴力,遍历亿遍,将最大的数 m a x max max都删去.

code 1.0:

#include<bits/stdc++.h>
using namespace std;
int n[9102],s,zx=2399,j;
string m;
int main(){
	cin >> m >> s;
	int l=m.size();
	for(int i=0;i<l;i++){
		n[i]=m[i]-'0';
		if(n[i]<zx && n[i]!=0)zx=n[i],j=i;
	}
	if(j==s){
		for(int i=j;i<l;i++)cout << n[i];
		return 0;
	}
	for(int i=1;i<=s;i++){
		if(i>j)break;
		int max=-1,o;
		for(int y=0;y<j;y++)if(n[y]>max)max=n[y],o=y;
		n[o]=-1;
	}
	if(s>j){
		for(int i=1;i<=s-j;i++){
			int max=-1,o;
			for(int y=j+1;y<l;y++)if(n[y]>max)max=n[y],o=y;
			n[o]=-1;
		}
	}
	for(int i=0;i<l;i++)if(n[i]!=-1)cout << n[i];
}

很显然这是行不通的,当我们交上去时,可以发现只得了28分,(逃).

我们花高价玩儿一个数据:

输入:

50074897 2

正确输出:

4897

实际输出:

004897

这时,我们发现像有0这样的数字,还要去掉开头的0,因此,代码如下:

code 2.0:

#include<bits/stdc++.h>
using namespace std;
int n[9102],s,zx=2399,j;
string m;
int main(){
	cin >> m >> s;
	int l=m.size();
	for(int i=0;i<l;i++){
		n[i]=m[i]-'0';
		if(n[i]<zx && n[i]!=0)zx=n[i],j=i;
	}
	if(j==s){
		for(int i=j;i<l;i++)cout << n[i];
		return 0;
	}
	for(int i=1;i<=s;i++){
		if(i>j)break;
		int max=-1,o;
		for(int y=0;y<j;y++)if(n[y]>max)max=n[y],o=y;
		n[o]=-1;
	}
	if(s>j){
		for(int i=1;i<=s-j;i++){
			int max=-1,o;
			for(int y=j+1;y<l;y++)if(n[y]>max)max=n[y],o=y;
			n[o]=-1;
		}
	}
	int qwq=0;
	while(n[qwq]==-1||n[qwq]==0)qwq++;
	for(int i=qwq;i<l;i++)if(n[i]!=-1)cout << n[i];
}

当我们兴奋递交上去时,发现只多了14分

继续逃

我们再花高价买玩儿一组数据:

输入:

68129545206 6

正确输出:

12206

实际输出:

12420

! ! !

我们忽略了一种数据,这种数据 m a x max max在后面,但是我们如果删去 m a x max max的话,反而没有删去前面的数小,比如说"219 1",按刚才的代码结果是"21",但实际上应该是"19"才对,因为删去’9’的话它只减少了198,而删去’2’它却减少了200.

结论:

从高位往后一直删掉那个比后面的数大的数,结果才最小

比如上面的"219 1", 2 > 1 2>1 2>1,所以应该删去’2’而不是’9’.

温馨提示:不要忘记’0’欧!

AC code:

#include<bits/stdc++.h>
using namespace std;
int s,o=0;
char n[392103];
int main(){
	cin >> n >> s;
	int l=strlen(n);
	while(s--){
		for(int i=0;i<l;i++){
			if(n[i]>n[i+1]){
				for(int j=i;j<l-1;j++)n[j]=n[j+1];//如果n[i]>n[i+1],删去这个数
				break;
			}
		}
		l--;
	}
	int p=0;
	while(n[p]=='0')p++;//0处理
	for(int i=p;i<l;i++)cout << n[i];
   if(p>=l)cout << "0";//0处理
}

结果当然是AC了(这不废话吗)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值