Ugly Problem
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1592 Accepted Submission(s): 530
Special Judge
Problem Description
Everyone hates ugly problems.
You are given a positive integer. You must represent that number by sum of palindromic numbers.
A palindromic number is a positive integer such that if you write out that integer as a string in decimal without leading zeros, the string is an palindrome. For example, 1 is a palindromic number and 10 is not.
You are given a positive integer. You must represent that number by sum of palindromic numbers.
A palindromic number is a positive integer such that if you write out that integer as a string in decimal without leading zeros, the string is an palindrome. For example, 1 is a palindromic number and 10 is not.
Input
In the first line of input, there is an integer T denoting the number of test cases.
For each test case, there is only one line describing the given integer s ( 1≤s≤101000 ).
For each test case, there is only one line describing the given integer s ( 1≤s≤101000 ).
Output
For each test case, output “Case #x:” on the first line where x is the number of that test case starting from 1. Then output the number of palindromic numbers you used, n, on one line. n must be no more than 50. en output n lines, each containing one of your palindromic numbers. Their sum must be exactly s.
Sample Input
2 18 1000000000000
Sample Output
Case #1: 2 9 9 Case #2: 2 999999999999 1
题目意思:
给你一个大数 10^1000 然后让你把这个数字拆成五十个以内的回文数字
拆的方法很关键~~
这里提供一种思路 是这样的 先判断当前数字是不是回文数 如果是 就保存并退出循环 否则 设置两个伪指针 从中间向两边遍历 如果发现了不相同的数字 就记录此时的指针位置 然后把整个左边的数字翻转到右边 比如 123456 我第一次会把这个数字拆成 123321 当然 如果右边指针所指的数字较小的话 反过来之后还要给两个指针的点重新赋值 比如 124356 我会先记录下来 右边指针里的内容是3 然后把串变成124421然后 在把串变成123321 这样就好了
还有一个很重要的问题是前导零 其实也没有很难判断 难在处理和细节 如果一个数字会出现前导零 比如100 或者 2000 这两种数字分别代表两种特殊的前导零情况 100这个数字 最佳情况是拆成99 + 1 但是 2000 就不能第一次拆成999 我们第一次会把它拆成 1991 所以前导零的情况还要看第一位是不是数字1 分情况~~
真的是恶心人~~
Devil is in the Details!!!
#include <iostream>
#include <cstdio>
#include <cstring>
#define debug() puts("What the fuck ~~~");
using namespace std;
const int N = 1006;
string ans[100];
string sub(string a, string b)
{
int i , j, k, s, flag = 1;
int tmpa[10005], tmpb[10005], c[10005];
string ans;
if (a.size() < b.size() || (a.size() == b.size() && a.compare(b) < 0)) {
string tmp = a;
a = b;
b = tmp;
flag = 0;
}
while (a.length() > b.length())b = '0' + b;
int len = a.length();
for (i = 0; i <len; i ++) {
tmpa[i] = a[i] - '0';
tmpb[i] = b[i] - '0';
}
for (i = len - 1; i >= 0; i --) {
if (tmpa[i] >= tmpb[i])
c[i] = tmpa[i] - tmpb[i];
else {
c[i] = 10 + tmpa[i] - tmpb[i];
tmpa[i - 1]--;
}
}
for (i = 0; i < len - 1; i ++) {
if (c[i] != 0)
break;
}
for (j = i; j < len ; j ++)
ans = ans + (char)(c[j] + '0');
if(!flag)ans='-'+ans;
return ans;
}
bool judge(string str)
{
int len = str.length();
int p, q;
p = 0, q = len - 1;
while (p < q) {
if(str[p] != str[q])
return false;
p ++, q --;
}
return true;
}
int main()
{
int Case = 1;
string str ,ss;
int _;
cin >> _;
while (_ --) {
int cnt = 0;
cin >> str;
while (true) {
if(judge(str)) {
if (str.length() != 1 || str[0] != '0') {
ans[cnt ++] = str;
break;
}
}
int len_str = str.length();
if(len_str & 1) {// 如果长度是奇数的话~~
string temp;
temp.clear();
int Left = len_str / 2 - 1;
int Right = Left + 2;
while(str[Left] == str[Right])Left--, Right++;
// 考虑奇数并且有前导零部分~~
if (Left == 0 && str[Right] == '0') {
temp.clear();
for (int i = 0; i < len_str - 1; i ++)
temp += '9';
if(str[0] != '1') {
temp.clear();
for (int i = 0; i < len_str; i ++) {
temp += (str[0] - 1);
}
}
}
else { // 奇数没有前导零部分
temp.clear();
char op = str[Right];
int mid = len_str / 2;
for (int i = 0; i <= mid; i ++)
temp += str[i];
int pos = mid - 1;
while (pos != -1) temp += temp[pos--];
if (str[Left] > str[Right]) {
temp[Left] = temp[Right] = op;
}
}
ans[cnt ++] = temp;
str = sub(str , temp);
}
else { //长度为偶数部分~~~
string temp;
int Left , Right;
Left = len_str / 2 - 1;
Right = Left + 1;
while (str[Left] == str[Right])Left--, Right++;
// 长度为偶数并且有前导零部分
if (Left == 0 && str[Right] == '0') {
temp.clear();
for (int i = 0; i < len_str - 1; i ++)
temp += '9';
// cout << temp << endl;return 0;
if(str[0] != '1') {
string test;
temp.clear();
for (int i = 0; i < len_str; i ++)
temp += (str[0] - 1);
}
}
else { // 左边比右边小
temp.clear();
char op = str[Right];
int mid = (len_str / 2) - 1;
for (int i = 0; i <= mid ; i ++)
temp += str[i];
int pos = mid;
while (pos != -1)temp += temp[pos--];
if(str[Left] > str[Right]) //左边比右边大
temp[Left] = temp[Right] = op;
}
// cout << "temp == " << temp << endl;
ans[cnt ++] = temp;
// cout << str << " - " << temp << " == " ;
str = sub(str , temp);
// cout << str << endl;
}
}
//cout << _ << endl;//continue;
cout <<"Case #" << Case ++ << ":" << endl;
cout << cnt << endl;
for (int i = 0; i < cnt; i++) {
cout << ans[i] << endl;
}
}
}
//21021215642310
//114451451201201204512078456210
//1111110000000000000000000001000110101010101010101010101010101010