[lnsyoj4029/luoguP4109/HEOI2015]定价

题意

\(x'\)\(x\) 去除后导零的值,则定义 \(f(x)=2(\lfloor\log_{10}x'\rfloor+1) - [x' \equiv 5 \pmod{10}]\),给定区间 \([L,R]\),求该区间中最小的 \(f(x)\) 值。

sol

一道贪心题,思想比较好想,我们需要使得前面的非 0 数字部分长度最小,且末尾尽可能为 \(5\)。具体实现中,我们可以运用倍增思想,向后枚举时使后面的 \(0\) 的部分长度不降,每次枚举判断其 \(f(x)\) 值,这样就可以 \(O(\log R)\) 地枚举,总时间复杂度 \(O(\log^2 R)\)

代码

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>

using namespace std;

const int K = 15;

int T;
int l, r;
int p[K];

int count(int x){
    int ans = 0;
    while (!(x % 10)) ans ++ , x /= 10;
    return ans;
}

int calc(int x){
    while (!(x % 10)) x /= 10;
    int ans = 0;
    if (x % 10 == 5) ans -- ;
    while (x) ans += 2 , x /= 10;
    return ans ;
}

int main(){
    p[0] = 1;
    for (int i = 1; i < 10; i ++ ) p[i] = p[i - 1] * 10;

    scanf("%d", &T);
    while (T -- ){
        scanf("%d%d", &l, &r);
        int ans = 0x3f3f3f3f, id;
        for (; l <= r; l += p[count(l)]){
            int t = calc(l);
            if (t < ans) ans = t, id = l;
        }
        printf("%d\n", id);
    }

    return 0;
}
posted @ 2024-08-15 19:46  是一只小蒟蒻呀  阅读(2)  评论(0编辑  收藏  举报