[计蒜客NOIP2017模拟] 机智的AmyZhi 【模拟】

那年一个雨季, A m y Z h i 在校门外弯身买参考书。
这时 S i r i u s R e n 走过来,一言不合甩给她一道“自认为”很难的题:

给你一个数字 N N 的范围是 1 1000000 ),求一个最小的正整数 M ,这个数字 M 的各个位的数字加上它本身之和恰好为 N

没有想到 A m y Z h i 秒解了这道题并把 N 大到了 10 18 甩回给了 S i r i u s R e n
S i r i u s R e n 苦苦思索,发现并不会这道题。
可怜 S i r i u s R e n 一世英名,在 A m y Z h i 面前却宛如智障少年。

题目是水题但是题面确实可以……

最常见的思路就是考虑从小到大枚举 M ,直到找到满足条件的那一个。但是这枚举的范围显然太大,而实际上我们可以确定这个范围。

假设 N 的位数为 N u m ,由于一个十进制数每位上的数字最大为 9 ,那么这个 M 加上它各个位上的和最大也就为 9 N u m ,所以我们枚举的下边界就是 N 9 N u m ,而实际上这样枚举的时间复杂度是可以承受的。

参考代码:

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define SG string
#define DB double
#define LL long long
using namespace std;
LL T,N;
inline LL Read(){
    LL X=0;char CH=getchar();bool F=0;
    while(CH>'9'||CH<'0'){if(CH=='-')F=1;CH=getchar();}
    while(CH>='0'&&CH<='9'){X=(X<<1)+(X<<3)+CH-'0';CH=getchar();}
    return F?-X:X;
}
inline void Write(LL X){
    if(X<0)X=-X,putchar('-');
    if(X>9)Write(X/10);
    putchar(X%10+48);
}
LL GetNum(LL X){
    LL Num=0;
    while(X!=0){
        Num++;X/=10;
    }
    return Num;
}
LL GetSum(LL X){
    LL Sum=0;
    while(X!=0){
        Sum+=X%10;X/=10;
    }
    return Sum;
}
int main(){
    LL I,J,K;
    T=Read();
    while(T--){
        N=Read();
        LL Num=GetNum(N);
        for(I=N-Num*9;I<=N;I++){
            LL Sum=GetSum(I);
            if(Sum+I==N){
                Write(I);putchar('\n');break;
            }
        }
        if(I==N+1){
            puts("Stupid SiriusRen");
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/yanzhenhuai/article/details/81099265
今日推荐