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';
	}
}

posted @   安潇末痕  阅读(12)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· Windows编程----内核对象竟然如此简单?
点击右上角即可分享
微信分享提示