B. Sum of Two Numbers

B. Sum of Two Numbers

The sum of digits of a non-negative integer a is the result of summing up its digits together when written in the decimal system. For example, the sum of digits of 123 is 6 and the sum of digits of 10 is 1. In a formal way, the sum of digits of a=i=0ai10i, where 0ai9, is defined as i=0ai.

Given an integer n, find two non-negative integers x and y which satisfy the following conditions.

  • x+y=n, and
  • the sum of digits of x and the sum of digits of y differ by at most 1.

It can be shown that such x and y always exist.

Input

Each test contains multiple test cases. The first line contains the number of test cases t (1t10000).

Each test case consists of a single integer n (1n109)

Output

For each test case, print two integers x and y.

If there are multiple answers, print any.

Example

input

5
1
161
67
1206
19

output

1 0
67 94
60 7
1138 68
14 5

Note

In the second test case, the sum of digits of 67 and the sum of digits of 94 are both 13.

In the third test case, the sum of digits of 60 is 6, and the sum of digits of 7 is 7.

 

解题思路

  经典思维题想不出来。比赛的时候想了很久,最后还是写暴搜过的,先贴个代码。

复制代码
#include <bits/stdc++.h>
using namespace std;

typedef long long LL;

int n;
vector<int> num;
int pow10[10];
int ans[2];

int get(int x) {
    int ret = 0;
    while (x) {
        ret += x % 10;
        x /= 10;
    }
    return ret;
}

bool dfs(int a, int b, int u, int r) {
    if (u == num.size() && a + b == n) {
        ans[0] = a, ans[1] = b;
        return true;
    }
    for (int i = 0; i <= 9; i++) {
        int j = ((num[u] - i - r) % 10 + 10) % 10;
        int t = abs(get(i * pow10[u] + a) - get(j * pow10[u] + b));
        if (t <= 1 && dfs(i * pow10[u] + a, j * pow10[u] + b, u + 1, (i + j) / 10)) return true;
    }
    return false;
}

void solve() {
    scanf("%d", &n);
    num.clear();
    for (int i = n; i; i /= 10) {
        num.push_back(i % 10);
    }
    pow10[0] = 1;
    for (int i = 1; i < num.size(); i++) {
        pow10[i] = pow10[i - 1] * 10;
    }
    dfs(0, 0, 0, 0);
    printf("%d %d\n", ans[0], ans[1]);
}

int main() {
    int t;
    scanf("%d", &t);
    while (t--) {
        solve();
    }
    
    return 0;
}
View Code
复制代码

  思路就是从低位开始往高位搜,假设n的第i位是aiy的第i位是bix的第i位是ci,然后从09枚举bi,那么ci=(aibir)mod10,其中r是来自低位的进位,同时还要满足bi+ciss是指允许两数相差的最大值。实际上加上这些约束条件的剪枝后有效状态是非常少的(大概十多个,其中只要看哪个位两数相差为1就好了),因此可以过。

  实际上这是道思维题来的。每一位都可以看作是独立的,因此可以没有进位。如果n是偶数的话那么直接x=y=n2就好了。否则n是奇数,枚举n的每一位,如果ai是偶数,那么bi=ci=ai2。如果ai是奇数,那么bici一个取ai2,一个取ai2,为了保证最后所有位数之和相差不超过1,可以交替地给bici分配较大的数和较小的数。

  AC代码如下:

复制代码
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 void solve() {
 5     int n;
 6     scanf("%d", &n);
 7     int a = 0, b = 0, s = 0;
 8     for (auto &c : to_string(n)) {
 9         int x = c - '0';
10         if (x & 1) {
11             a = a * 10 + (x + s) / 2;   // s是奇数,那么把较大的数分配给a
12             b = b * 10 + (x + !s) / 2;  // s是偶数,那么把较大的数分配给b
13             s ^= 1;
14         }
15         else {
16             a = a * 10 + x / 2;
17             b = b * 10 + x / 2;
18         }
19     }
20     printf("%d %d\n", a, b);
21 }
22 
23 int main() {
24     int t;
25     scanf("%d", &t);
26     while (t--) {
27         solve();
28     }
29     
30     return 0;
31 }
复制代码

 

参考资料

  Codeforces Round #851 (Div. 2) Editorial:https://codeforces.com/blog/entry/112584

posted @   onlyblues  阅读(181)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
Web Analytics
点击右上角即可分享
微信分享提示