题目描述:给定一个n(2<=n<=1e5)位数,要是找到另一个n位数,使这两数之和为回文数。(两数及回文数均不含前导0)
example:
2 99 4 1023 3 385
32 8646 604
原本想着根据给的数,来构造答案,但具体过程实在太难,因为可能有进位影响,而且还要回文(失败)。所以中间的构造过程其实是不好想的,但是有一点是非常容易确定的,就是回文数的位数,因为不含前导0,所以如果最高位是9,那么得到的回文数的最高位一定是进位了,而且为1,那么我们就可以直接确定回文数,即数位全的1,如果最高数位不是9,那么我们可以构造最高位是9的回文数,进一步,数位全为9。这两种情况的数一定比给定的数大(因为最高位进位或直接构造9),问题就简单了,拿我们构造的回文数减去给定的数,就得到答案。
(有时候,不能过于顺着题目的意思去思考,要多剖析,找到突破口)
#include<iostream>
#include<string>
#include<memory.h>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<algorithm>
#include<functional>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N = 1e5 + 7;
int s[N];
int a[N];
void solve()
{
memset(s, 0, sizeof(s));
int n;
cin >> n;
for (int i = n - 1; i >= 0; i--)
{
char ch;
cin >> ch;
a[i] = ch - '0';
}
if (a[n - 1] == 9)
{
for (int i = 0; i <= n; i++) s[i] = 1;
}
else
{
for (int i = 0; i < n; i++) s[i] = 9;
}
for (int i = 0; i < n; i++)
{
if (s[i] - a[i] >= 0) s[i] -= a[i];
else
{
s[i] = s[i] + 10 - a[i];
s[i + 1]--;
}
}
int now = n + 1;
while (now >= 0 && s[now] == 0) now--;
for (int i = now; i >= 0; i--) cout << s[i];
cout << endl;
}
int main()
{
int t = 1;
cin >> t;
while (t--)
solve();
return 0;
}