N. Number Reduction—codeforces每日一题

🚀前言 🚀

大家好啊,这里是幸麟

🧩 一名普通的大学牲,最近在学习算法

🧩每日一题的话难度的话是根据博主水平来找的

🧩所以可能难度比较低,以后会慢慢提高难度的

🧩此题标签: *1500  贪心

🧩本文栏目:一起来打cf吧

期待各位的点赞+收藏+关注,订阅专栏,每天一起写一道cf吧

一起学习算法吧

题目

题目链接:Problem - N - Codeforces

题目:

 样例:

 题目大意:

给你一个数x,你可以对这个数的任意一位进行删除,可以删除k次,希望你找到经过k次删除后最小的正数x

输入:

一个t代表测试组数

接下来有t组输入,每组包括两行,第一行为x,第二行为可以进行的删除操作k

输出:

输出t行,每一行为对应组别的最小正数x

输出:

比如7808652,你可以进行4次删除,删除后最小的正数x为7052

往下面翻就是答案了(想继续思考的话,还是不要往下面翻了)

答案+思路

因为x的位数比较大,所以这里我们用字符串s来存储x的每一位

用ans来表示经过k次删除后的x

我们已知k,所以经过k次删除后,ans的位数为s.size()-k

要让ans尽量小,我们可以选择尽量小的数字组成ans前面几位

比如在选择ans第一位的时候,我们可以先尝试能不能让1成为ans的首位,如果不能就尝试2,以此类推,在选择ans后面的位数时,则先尝试能不能让0成为首位,如果不能再一次试试1~9

如果可以找到这个数字,那我们就对x进行删除操作,直到删到选择数字的最小下标即可

具体可以再看看注释

#include <iostream>
#include <queue>
#include <map>
#include <unordered_map>
#include <vector>
#include <algorithm>
#include <cmath>
#include <string>
#include <cstring>
#include <set>
using namespace std;
typedef long long ll;
string s;
int main()
{
	int t;
	cin >> t;
	while (t--)
	{
		int k;
		int idx[10] = { 0 };
		vector<int>a[10];
		string ans;
		cin >> s >> k;
		for (int i = 0; i < s.size(); i++)
		{
			a[s[i] - '0'].push_back(i);//存每位数的下标
		}
		int l = 0;//l为删除的起点
		int flag = 0;
		while (k)
		{
			for (int i = 0; i <= 9; i++)
			{

				if (a[i].size() > idx[i] && (l > 0 || i != 0))
				{

					if (a[i][idx[i]] <= l + k)
					{
						k = k - (a[i][idx[i]] - l);
						l = a[i][idx[i]] + 1;
						idx[i]++;
						ans += char(i + '0');
						for (int x = 0; x <= 9; x++)//更新最小下标
						{
							if (a[x].size() > idx[x])
							{
								while (a[x][idx[x]]<l)
								{
									idx[x]++;
									if (a[x].size() == idx[x])
									{
										break;
									}
								}
							}
						}
						break;
					}
				}
			}
			if (k + l >= s.size())//删除的起点+还可以删除的次数大于了x的位数就可以不用删除了
			{
				flag = 1;
				break;
			}
		}
		if (flag)//ans就是答案
		{
			cout << ans << endl;
		}
		else//ans是答案的前几位
		{
			cout << ans;
			for (int i = l; i < s.size(); i++)
			{
				cout << s[i];
			}
			cout << endl;
		}
	}
	
	return 0;
}

好了,今天的每日一道到此结束了,

我发现了,好像1400~1600这个区间的,大部分题目都是贪心

马上就要期末考了,但是课上的记忆在离我远去

复习去了

 

  • 9
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

幸麟同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值