B. Sum of Two Numbers
B. Sum of Two Numbers
The sum of digits of a non-negative integer is the result of summing up its digits together when written in the decimal system. For example, the sum of digits of is and the sum of digits of is . In a formal way, the sum of digits of , where , is defined as .
Given an integer , find two non-negative integers and which satisfy the following conditions.
- , and
- the sum of digits of and the sum of digits of differ by at most .
It can be shown that such and always exist.
Input
Each test contains multiple test cases. The first line contains the number of test cases ().
Each test case consists of a single integer ()
Output
For each test case, print two integers and .
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 and the sum of digits of are both .
In the third test case, the sum of digits of is , and the sum of digits of is .
解题思路
经典思维题想不出来。比赛的时候想了很久,最后还是写暴搜过的,先贴个代码。

#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; }
思路就是从低位开始往高位搜,假设的第位是,的第位是,的第位是,然后从枚举,那么,其中是来自低位的进位,同时还要满足,是指允许两数相差的最大值。实际上加上这些约束条件的剪枝后有效状态是非常少的(大概十多个,其中只要看哪个位两数相差为就好了),因此可以过。
实际上这是道思维题来的。每一位都可以看作是独立的,因此可以没有进位。如果是偶数的话那么直接就好了。否则是奇数,枚举的每一位,如果是偶数,那么。如果是奇数,那么和一个取,一个取,为了保证最后所有位数之和相差不超过,可以交替地给和分配较大的数和较小的数。
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
本文来自博客园,作者:onlyblues,转载请注明原文链接:https://www.cnblogs.com/onlyblues/p/17111272.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效