目录
1.初始分析
首先,我们分析数据范围,高达10的九次方的数据范围一定不能用on的遍历枚举。也就是说,我们需要一个o1的结论性质的东西。
很明显的思路就是,偶数平分,奇数一个向上取整一个向下取整,大部分情况下,这样保证了答案的正确,但是样例的最后一个19-10和9
我们明显发现这一错误,这一操作可能会让某个数字变成10的倍数,但是样例中另一个161-81,80却是符合条件的,于是我们得到了结果之一:向上取整的如果是10的倍数需要它特殊分析。
2.进行数位平均分配。
在苦思冥想也想不到解决方案后,我们只能够回到最初的位置:尽可能地平均分配。
why?
因为我们要求的是各个数位的和相差不超过1,那么我们在将n分成各个数位后,如果是偶数那么平均分配,不会对答案产生影响。
那么,奇数呢?
也很简单,用一个cnt进行标记,如果上一次我们给a多分了1,那么下一次就给b多分1。这样,我们很容易就能将数位上的每一个数字都平均分配了。
3.代码展示(有注释)
#include <bits/stdc++.h>
using namespace std;
#pragma GCC optimize(2)
void solve(int n) {
stack<int>st;
int cnt = 0, a = 0, b = 0, tmp;
while (n) {
st.push(n % 10); //每一次将个位加入到栈中,到最后,最高位在第一层,保证在取出时最高位能够乘以更多的数字
n /= 10;
}
while (st.size()) {
tmp = st.top();
st.pop();
if (tmp % 2 == 0) { //为了保证均分,当取出偶数时,就能够平均分配,因此就能够分给a,b;
a = a * 10 + tmp / 2;
b = b * 10 + tmp / 2;
continue;
}
if (cnt % 2 == 0) { //我们设定偶数位a多加一,奇数位b多加一,
a = a * 10 + tmp / 2 + 1;
b = b * 10 + tmp / 2;
cnt += 1;
} else {
a = a * 10 + tmp / 2 ;
b = b * 10 + tmp / 2 + 1;
cnt += 1;
}
}
cout << a << " " << b << "\n";
return;
}
int main() {
ios::sync_with_stdio(false);
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
if (n % 2 == 0) {
cout << n / 2 << " " << n / 2 << "\n";
} else if (n % 2 != 0) {
if ((n / 2 + 1) % 10 != 0 ) {
cout << n / 2 << " " << n / 2 + 1 << "\n";
continue;
}
solve(n);
}
}
return 0;
}