一、题意: 输入一个数字,要求每次减去一个回文数,在50次以内减到0,输出次数和每个减去的回文数。
二、思路: 因为是大数,所以涉及到大数的加减,需要用字符串模拟。
我们每次可以取字符串的前面一半,然后-1,再将该数字反转,拼凑起来形成一个回文数。
因为-1,所以形成的数字一定比原来的数字要小,但在这里要注意原数字的奇偶性。
cpp代码
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<map>
#include<queue>
#include<vector>
#include<stack>
//#define int long long
using namespace std;
vector<string>v;
string solve(string str1, string str2) {
string ans;
reverse(str1.begin(), str1.end());
reverse(str2.begin(), str2.end());
while (str2.size() < str1.size())str2 += '0';
for (int i = 0; i < str1.size(); i++) {
if (str1[i] < str2[i]) {
str1[i + 1]--;
str1[i] += 10;
}
ans += str1[i] - str2[i] + '0';
}
reverse(ans.begin(), ans.end());
while (ans[0] == '0')ans.erase(0, 1);
return ans;
}
int main()
{
ios::sync_with_stdio(0);
int t;
cin >> t;
int t1 = 1;
while (t--) {
v.clear();
string str;
cin >> str;
while (str.size() != 1) {
if (str.size() == 2 && str[0] == '1') {
v.push_back("9");
str[0] = 10 + (str[1] - '0') - 9 + '0';
str.erase(1, 1);
continue;
}
int mid = str.size() / 2;
string now = "";
if (str.size() % 2 == 0) {
for (int i = 0; i < mid; i++)
now += str[i];
now = solve(now, "1");
int len = now.size();
for (int i = len - 1; i >= 0; i--)now += now[i];
}
else {
for (int i = 0; i <= mid; i++)now += str[i];
now = solve(now, "1");
int len = now.size();
if (now.size() * 2 > str.size())
for (int i = len - 2; i >= 0; i--)now += now[i];
else
for (int i = len - 1; i >= 0; i--)now += now[i];
}
v.push_back(now);
str = solve(str, now);
}
if (str.size() == 1 && str[0] != 0)
v.push_back(str);
cout << "Case #" << t1++ << ":" << endl << v.size() << endl;
for (int i = 0; i < v.size(); i++)
cout << v[i] << endl;
}
return 0;
}