题目描述
难度分:1100
输入T(≤104)表示T组数据。每组数据输入n(1≤n≤109)。
定义digsum(a)表示a的数位和。构造两个非负整数x和y,满足x+y=n且|digsum(x)−digsum(y)|≤1。
可以证明,这样的x和y一定存在。
输入样例
5
1
161
67
1206
19
输出样例
1 0
67 94
60 7
1138 68
14 5
算法
构造
如果n是偶数,那么x=y=n2,两者的数位和完全相等。如果n是奇数,就从高到低遍历n的数位d,逐位构造x和y。如果d是偶数,让x和y在这一位均分d;如果d是奇数,就让数位和小的那个数获得⌈n2⌉,数位和大的那个数获得⌊n2⌋。
复杂度分析
时间复杂度
当n是奇数时,需要遍历它的各个数位,因此单个case的时间复杂度为O(log10n)。T个case的时间复杂度为O(Tlog10n)。
空间复杂度
由于从高到低遍历n的数位,所以将n转化为字符串遍历会更方便。字符串的长度为O(log10n),预留这部分空间给每个case使用即可。因此,额外空间复杂度为O(log10n)。
C++ 代码
#include <bits/stdc++.h>
using namespace std;
int t, n;
int main() {
scanf("%d", &t);
while(t--) {
scanf("%d", &n);
if(n&1) {
string s = to_string(n);
bool gt = false, lt = false;
int num1 = 0, num2 = 0;
for(int i = 0; i < s.size(); i++) {
int d = s[i] - '0';
if(d&1) {
if(gt) {
int d1 = d>>1, d2 = d + 1>>1;
num1 = 10*num1 + d1;
num2 = 10*num2 + d2;
gt = false;
lt = true;
}else {
int d1 = d + 1>>1, d2 = d>>1;
num1 = 10*num1 + d1;
num2 = 10*num2 + d2;
gt = true;
lt = false;
}
}else {
int d1 = d>>1, d2 = d>>1;
num1 = 10*num1 + d1;
num2 = 10*num2 + d2;
}
}
printf("%d %d\n", num1, num2);
}else {
printf("%d %d\n", n>>1, n>>1);
}
}
return 0;
}