删数问题
删数问题
题目描述
键盘输入一个高精度的正整数
输入格式
输入两行正整数。
第一行输入一个高精度的正整数
第二行输入一个正整数
输出格式
输出一个整数,最后剩下的最小数。
样例 #1
样例输入 #1
175438
4
样例输出 #1
13
题解1
规律:
4:
1 4 1 5 1 9
留 删 留 删 留 留
2:
1 5 1 9
留 删 留 删
会发现我们删除的是一个山峰,也就是比后一个数要大的数,且越靠前的山峰
规律:删除靠前的“山峰”,执行k次
Tips: 注意最后要删前缀0
#include <bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define ppb pop_back
#define SZ(v) ((int)v.size())
typedef long long ll;
typedef unsigned int u32;
typedef unsigned long long u64;
typedef double db;
using namespace std;
const int N = 1e5+5;
string s;
int n;
int main() {
cin >> s >> n;
int len = SZ(s);
while(n--) { // 删除n个数字
for(int i = 1; i < len; i++) {
if(s[i] < s[i-1]) { //找到一个前驱值大于当前值
for(int j = i; j < len; j++) { //将该前驱值删除
s[j-1] = s[j];
}
break;
}
}
len--;
}
int i = 0;
while(i <= len-1 && s[i] == '0') { //删除前缀0,若所有为0,则保留一个0
i++;
}
if(i == len) {
cout << "0\n";
return 0;
}
for(; i < len; i++) {
cout << s[i];
}
return 0;
}
题解2
这里可以把删数问题理解成选数问题:从n个数中选择n-k个数
采用滑动数组的方法 :
初始的滑动区间是[1, n-k],从区间找到最小值,并记录最小值minn的位置
第i次循环滑动区间右边界+i,滑动区间[minn+1, n-k+i]
#include <bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define ppb pop_back
#define SZ(v) ((int)v.size())
typedef long long ll;
typedef unsigned int u32;
typedef unsigned long long u64;
typedef double db;
using namespace std;
const int N = 1e5+5;
int n;
string s;
char c[200];
int main() {
cin >> s >> n;
int len = SZ(s);
int k = -1; // 上一个选的数的位置
int cnt = 0; // 已经选的个数
int sy = len - n; // 挑选sy个数
while(sy-cnt!=0) {
int minn = INT_MAX;
for(int i = k+1; i <= len-sy+cnt; i++) { //每次选一个最小的数且位置最靠前
if(s[i] < minn) {
minn = s[i];
k = i;
}
}
c[cnt++] = s[k];
}
int i = 0;
while(sy - i - 1 != 0 && c[i] == '0') i++;
for(; i < cnt; i++) {
cout << c[i];
}
cout << "\n";
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话