ACdream OJ sgx和路飞 (二分答案+数位统计)

ACdream在梦中遇到路飞,为避免被吃穷,他提出一个问题:在自然数区间[A,B]内找到各位数字之和为S的最小数。这是一个关于数位统计和二分查找的问题,需要帮助路飞解决。" 124332213,13203166,HTML基础教程:从入门到精通,"['HTML', '前端开发', 'Web开发', '标记语言']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

sgx和路飞

Time Limit: 2000/1000 MS (Java/Others)  Memory Limit: 128000/64000 KB (Java/Others)
Problem Description

众所周知,sgx是个海贼迷。每个礼拜更新的海贼王他都不会放过。这天晚上,他码完代码结果迷迷糊糊困得睡着了。梦中,他见到了偶像路飞。路飞碰巧没吃东西,想要去sgx家吃东西。大家都知道,路飞是个大胃王。让他敞开吃的话sgx家就被吃穷了。但是又不能不让他吃。所以sgx就出了个题目给他:

在所有自然数集合中,给出区间[A,B],求在此区间内各位数字之和为S的最小数。
你们都是热心的海贼迷,可不能看着路飞饿肚子,而路飞又不懂代码,所以这个艰巨的任务就交给你们完成了。

Input
输入包含三个整数A, B, S   (1 ≤ A ≤ B <= 10^18, 1 ≤ S ≤ 162).
Output
满足上述条件的最小元素数值。数据保证答案一定存在。
Sample Input
1 100 10
Sample Output
19
Hint

在1到100之间满足各位数字之和相加等于10的数字最小是19.


#include <stdio.h>
#include <string.h>
 
const long long INF=1000000000000000000LL;
long long dp[20][200],l,r,mid,ans;
int num[20],len;
long long a,b;
int s;
 
inline long long dfs(int i,int sum,bool e){
    if(i==-1) return sum==s;
    if(!e && dp[i][sum]!=-1) return dp[i][sum];
    long long ans=0;
    int v=(e?num[i]:9);
    for(int j=0;j<=v;j++){
        ans+=dfs(i-1,sum+j,e&&(j==v));
    }
    if(!e) dp[i][sum]=ans;
    return ans;
}
inline long long solve(long long a){
    len=0;
    while(a){
        num[len++]=a%10;
        a/=10;
    }
    return dfs(len-1,0,1);
}
 
int main(){
    while(~scanf("%lld%lld%d",&a,&b,&s)){
        memset(dp,-1,sizeof dp);
        l=a,r=b;
        int cnt=0;
        while(cnt<=64){
            mid=l+(r-l)/2;
            long long sum=solve(mid)-solve(l-1);
            if(sum==0) l=mid+1;
            else r=mid-1;
            cnt++;
        }
        printf("%lld\n",l);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值