Final Countdown 题解

Problem Link

简要题意

把一个数不断减一直到变成零,每个数位变化一次需要一秒。

比如 \(300\) 变成 \(299\) 需要 \(3\) 秒。

求把一个数变成零要多少秒。

思路

对于每一位分开讨论它修改的次数发现。

把一个数 \(x\) 变成零的总次数其实就是
\(\sum \limits _{i=0}^n \lfloor \frac{x}{10^i} \rfloor\) 其中 \(n\) 是这个数字的位数。

比如 \(12345\) 变化次数

就是 \(12345 + 1234 + 123 +12 +1\)

但是数字太大需要使用高精度。

观察发现第 \(i\) 位是前 \(n-i+1\) 个数的和的个位,所以维护前缀和,然后进行高精度就行。

code

#include <cstdio>
#include <vector>
#include <algorithm>

using i64 = long long ;

const int N = 4e5 + 5 ;

char s[N];

void solve(){

    int n;
    scanf("%d",&n);

    scanf("%s",s+1);
    
    std::vector<int> sum(n+10,0);
    std::vector<int> ans(n+10,0);

    for(int i = 1; i <= n; i++) 
        sum[i] = sum[i-1] + s[i]-'0';
    
    std::vector<int> add(n+10,0);
    for(int i = 1; i <= n; i++) {
        int x = (sum[n-i+1] + add[i])/10;

        ans[i] = (sum[n-i+1] + add[i])%10;

        add[i+1] += x; //维护进位
    }

    if(add[n+1])
        ans[n+1] = add[n+1],n++;

    while(ans[n] == 0) n--; //去掉前导零
    for(int i = n; i >= 1; i--)
        printf("%d",ans[i]);

    puts("");
}

int main(){
    
    int t;
    scanf("%d",&t);
    
    while(t--) solve();
    return 0;
}
posted @ 2024-03-14 21:07  Z_drj  阅读(6)  评论(0编辑  收藏  举报