大体题意:

给你一个长度不超过1000的大数,划分成n 个回文串,使得回文串的个数不超过50,并且回文串的和是这个大数!

思路:

大数模拟!

最长长度为1000    个数不超过50,显然必须是log级别的,也就是接近折半的运算!

所以我们先根据这个大数的前一半算出这个回文串是多少来,如果这个回文串小于当前的大数,直接减,在继续递归寻找!

如果大于当前大数, 你就必须找到一个非常接近它的回文串,其实也很好想,找到前一半,让前一半减1,这样在构造出的回文串一定小于当前大数,在继续递归即可!

比如说34567  直接构造34543 递归即可!

如果是 34511  构造出来34543  不能继续减,就让345减1,得344,构造出来的是34443 可以继续减,并且接近折半运算!

教训:

这种恶心的题目应对起来 可以写几个debug函数 看看哪里错了,这样更容易查错!

详细见代码:


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <iostream>
#include <vector>
#include <assert.h>
using namespace std;
const int maxn = 2000 + 1;
vector<string>sans;
int cmpe(string s1,string s2){  // s1 > s2 = 1  s1 = s2 = 0 s1 < s2 = -1
    int len1= s1.length();
    int len2= s2.length();
    if (len1 > len2) return 1;
    else if (len1 < len2) return -1;
    else {
        if (s1 > s2) return 1;
        else if (s1 < s2) return -1;
        return 0;
    }
}
bool judge(string s){
    int len = s.length();
    for (int i = 0; i < (len+1)/2; ++i){
        if (s[i] != s[len-i-1])return false;
    }
    return true;
}
/**
1111111111111111110
 998877665544332211
01122334455667789/9
**/
string Mul(string s1,string s2){
    int len1 = s1.length();
    int len2 = s2.length();
    string ans = "";
    int tmp = len1-len2;
    int flag = 0;
    for (int i = len2-1; ~i; --i){
        if (s1[i+tmp]-flag >= s2[i]){
            ans = char(s1[i+tmp] - s2[i] - flag + 48) + ans;
            flag = 0;
        }
        else{
            ans = char(s1[i+tmp] + 10 - s2[i] - flag + 48) + ans;
            flag = 1;
        }
    }
    for (int i = tmp-1; ~i; --i){
        if (s1[i] - 48 - flag >= 0) ans = char(s1[i] - flag) + ans,flag = 0;
        else ans = char(s1[i] - flag + 10) + ans,flag = 1;
    }
    int p = 0;
    int anslen = ans.length();
    while(p < anslen && ans[p] == 48)++p;
    if (p != 0){
        if (p == anslen){
            ans[0] = 48;
            ans[1] = 0;
            ans.resize(1);
            return ans;
        }
        for (int i = 0; i < anslen - p; ++i){
            ans[i] = ans[i+p];
        }
        ans.resize(anslen-p);
    }
    return ans;
}
string unit = "1";
void deal(string s){
    if (judge(s)){
        sans.push_back(s);
        return;
    }
    int len = s.length();
    string t1;
    t1.resize(len);
    for(int i = 0; i < ((len&1)?len/2+1:len/2); ++i){
        t1[i] = t1[len-i-1] = s[i];
    }
    string t2;
    if (cmpe(s,t1) != -1){
        sans.push_back(t1);
        t2 = Mul(s,t1);
        deal(t2);
    }
    else {
        bool ok = 0;
        for (int i = 1; i < len-1; ++i) if (t1[i] != '0'){
            ok = 1;
            break;
        }
        if (!ok && t1[0] == t1[len-1] && t1[0] == 49){
            string zha = "1";
            sans.push_back(zha);
            zha = "";
//            puts("1");
            for (int i = 1; i < len; ++i) zha += "9";
            sans.push_back(zha);
            return;
        }

        t1.resize(len+1>>1);
        t2 = Mul(t1,unit);
        t2.resize(len);
        for (int i = 0; i < len/2; ++i){
            t2[len-i-1] = t2[i];
        }
        sans.push_back(t2);
        t1 = Mul(s,t2);
        deal(t1);
    }

}
char s[maxn];
void print(vector<string>& aa){
    printf("%d\n",aa.size());
    for (int i = 0; i < aa.size(); ++i)printf("%s\n",aa[i].c_str());
}
int main(){
//    debug();
    int T,ks = 0;
    scanf("%d",&T);
    while(T--){
        sans.clear();
        scanf("%s",s);
        printf("Case #%d:\n",++ks);
        deal(s);
        print(sans);
    }
    return 0;
}



Ugly Problem


Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 898    Accepted Submission(s): 311
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.


 



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).


 



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


Hint


 



Source


2016中国大学生程序设计竞赛(长春)-重现赛


 



Recommend


wange2014   |   We have carefully selected several similar problems for you:   5932  5931  5930  5929  5928