hdu 5920(高精度 + 模拟)

来源:互联网 发布:饥荒mac版mod 编辑:程序博客网 时间:2024/06/05 14:09

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.
 

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 (1s101000).
 

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
2181000000000000
 

Sample Output
Case #1:299Case #2:29999999999991


题目意思:

给你一个大数 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




原创粉丝点击