最开始我没看清题干,想着打个表暴力破解一波,直接白给还浪费大把时间,但是实际上题目给的数据极大,需要用到高精度减法
具体思路:题目要求给定一个数m,输出一个数ans使得ans+m的值为回文数,并且ans和m的长度相等,都为cnt(也就是二者数量级一致),可以直接构造一个足够大的回文数减去m得到ans,具体分为两种情况,
1、m的第一位为9,需要进位则构造回文数11...11,例如m=99 构造回文数111,回文数比m多一位
2、m的第一位不为为9,则不需要进位,构造回文数99..99,例如m=91 构造回文数99,回文数和m位数相等
#include<iostream>
#include<math.h>
#include<vector>
#include<algorithm>
#define mem(a,b) memset(a,b,sizeof(a))
#define ll long long
#define oo 0x3f3f3f3f
#define x first
#define y second
const int maxn = 2e5 + 10;
using namespace std;
long long num[100000]={0};
int len;
string m;
int cmp(string m, string n)
{
if (m.length() != n.length())
return m.length() < n.length();
else
{
for (int i = 0; i <= m.length() - 1; i++)
{
if (m[i] != n[i])
return m[i] < n[i];
}
}
}
void slove(string m)
{
vector<int> a, b, c;
string n;
if (m[0] != '9')//构造999
for (int i = 1; i <= len; i++)
n += '9';
else
for (int i = 1; i <= len + 1; i++)//构造1111
n += '1';
if (cmp(m, n))//比较大小,使得m大于n
{
string t;
t = m;
m = n;
n = t;
}
for (int i = 0; i < m.length(); i++)
a.push_back(m[m.length() - 1 - i] - 48);//将数字从个位到最高位,逆序放入动态数组
for (int i = 0; i < n.length(); i++)
b.push_back(n[n.length() - 1 - i] - 48);
int cnt = 0;
while (cnt < a.size() && cnt < b.size())
{
if (a[cnt] < b[cnt])//不够就借位相减,
{
a[cnt] += 10;
a[cnt + 1]--;
}
c.push_back(a[cnt] - b[cnt]);
cnt++;
}
for (int i = cnt; i < a.size(); i++)//如果最后数组中还有剩的数字直接补上c数组
c.push_back(a[i]);
for (int i = c.size() - 1; i >= 0; i--)//反向输出
{
if (i == c.size()-1 && c[i] == 0)
continue;
cout << c[i];
}
cout << "\n";
}
int main()
{
int t;
cin >> t;
int cnt = 1;
while (t--)
{
cin >> len;//位数
cin >> m;//给定数字
slove(m);
}
return 0;
}