cf-div.2-861c
题目链接:https://codeforces.com/contest/1808/problem/C
又是被打爆的一场比赛。。。(本题想了一个多小时也没有想到最核心的地方。)
大致题意:让你从\([l,r]\)选择一个数字,使得它其中的数位的最大值减最小值最小。
\(l,r\)的范围都取到long long级别。
思路:单纯暴力枚举一定不行。注意到一个性质,一个数字里的数位相同的数字越多,他一定不会变得更差,
所以,答案一定包含这样一种情况,前n位与l或r的前n位相同,后面全部取一样的数字,这样情况就少了很多,但最优解的子集一定包含在我们所枚举的范围里。
代码:
#include<iostream>
#include<cstring>
#include<vector>
using namespace std;
using LL = long long;
int main(){
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
auto get = [&](LL x){
int mn = 10, mx = -1;
while(x){
mn = min(1LL * mn, x % 10);
mx = max(1LL * mx, x % 10);
x /= 10;
}
return mx - mn;
};
int T;
cin >> T;
while(T--){
LL l, r;
cin >> l >> r;
int a[20], b[20];
int len1 = 0, len2 = 0;
LL num = l;
while(num) a[++len1] = num % 10, num /= 10;
num = r;
while(num) b[++len2] = num % 10, num /= 10;
int ans = 10;
LL val = -1;
LL x = 0;
for (int i=len1;i>=0;i--){
for (int j=0;j<=9;j++){
LL t = x;
for (int k=i;k>=1;k--){
t = t*10+j;
}
if (t>r||t<l) continue;
if (get(t)<ans) ans = get(t),val = t;
}
x = x*10+a[i];
}
x = 0;
for (int i=len2;i>=0;i--){
for (int j=0;j<=9;j++){
LL t = x;
for (int k=i;k>=1;k--){
t = t*10+j;
}
if (t>r||t<l) continue;
if (get(t)<ans) ans = get(t),val = t;
}
x = x*10+b[i];
}
cout<<val<<'\n';
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· Windows编程----内核对象竟然如此简单?