CF1788B Sum of Two Numbers 题解

题意概述

设 $ f(x) $ 为 $ x $ 上的各个数位之和。

给定一正整数 $ n $,求正整数 $ x,y $ 使得 $ x + y = n $ 且 $ | f(x) - f(y) | \le 1 $。

Sol 1

显然可以发现,若 $ n $ 的个位不是 $ 9 $,则合法的一种拆分可以是:

$$ \begin{cases} & \text{ x = n/2,y = n/2 if } n \bmod 2 = 0 \\ & \text{ x = (n + 1) / 2,y = (n - 1) / 2 if } n \bmod 2 = 1 \end{cases} $$

可以这样感性理解:

如果为偶数,可以构造 $ x = y $,显然符合条件。

如果为奇数,则个位可能是 $ 1,3,5,7 $,新数的个位分别为 $ (0,1),(1,2),(2,3),(3,4) $,均不向前借位或进位(不影响前面)。

若 $ n $ 的个位是 $ 9 $,可以将所有后缀 $ 9 $ 与除去后缀 $ 9 $ 的数 $ s $ 单独分开考虑。

由于不包括后缀 $ 9 $,$ s $ 显然可以被合法拆分。

然后再将一堆连续的 $ 9 $ 拆分,一种拆分方案是拆成一堆 $ 4 $ 和 $ 5 $,例如 $ 9999 $ 拆成 $ 4455 $ 和 $ 5544 $。

最后把两步拆分的结果加起来就好了。

代码(奇丑无比):

#include<iostream>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<algorithm> 
#define ll long long

using namespace std;

struct node{
    ll a, b;
};

ll sum(ll x){
    ll cnt = 0;
    while(x != 0){
        cnt += x % 10;
        x /= 10;
    }
    return cnt;
}

node de(ll n){
    ll a, b;
    ll pos = 1, t = n, cnt = 0;
    while(t > 0){
        if(t % 10 == 9){
            pos *= 10;
            cnt++;
            t /= 10;
        }else{
            break;
        }
    }
    a = (n / pos) / 2;
    b = (n / pos) - a;

    for(ll i = 1; i <= (cnt >> 1); i++){
        a *= 10, b *= 10;
        a += 4, b += 5;
    }
    for(ll i = (cnt >> 1) + 1; i <= cnt; i++){
        a *= 10, b *= 10;
        a += 5, b += 4;
    }
    return (node){a,b};
}

int main(){

    ll T;
    cin >> T;
    while(T--){
        ll n;
        cin >> n;
        if(n % 10 == 9){
            if(abs(sum(n/2) - sum(n/2+1)) <= 1){
                cout << n/2 << " " << n/2+1 << '\n'; 
            }else{
                node t = de(n);
                cout << t.a << " " << t.b << '\n'; 
            } 
        }else{
            if(n & 1){
                cout << n/2 << " " << n/2+1 << '\n'; 
            }else{
                cout << n/2 << " " << n/2 << '\n'; 
            }
        }
    }
    return 0;
}

Sol 2

机房大佬的思路 %%%

大概就是对每一位都平均分配,如果当前位是偶数显然可以平均分;对于奇数的情况,如果当前位置是第奇数个奇数,那么就令 $ a $ 取较大的那位值,如果当前位置是第偶数个奇数,那么就令 $ b $ 取较大的那位值。

posted @ 2023-02-10 23:19  象征阳光  阅读(13)  评论(0)    收藏  举报  来源