hdu 5920 Ugly Problem(构造题)

来源:互联网 发布:java语言的特点是什么 编辑:程序博客网 时间:2024/06/07 09:41

Ugly Problem

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
Case #1:
2
9
9
Case #2:
2
999999999999
1

Hint

9 + 9 = 18
999999999999 + 1 = 1000000000000



思路:回文数就是从前数第几位和从后数第几位都相同的数

那么大致就是我们可以先把这个数str的一半长所代表的数s找到,然后用s-1来构造回文数ss,ss肯定比原先的数str要小,因此这样构造的ss就是比较优的解了

(其实比如说156,可以构造151,而我的算法是141,所以我的最后可能会比最优的算法多构造一个数)

代码:

#include<bits/stdc++.h>using namespace std;struct node//存储构造的答案{    string s;} p[100];int tmpa[10000],tmpb[10000],c[10000];string sub(string a,string b)//大整数减法{    int i,j,k,s,flag=1;    memset(tmpa,0,sizeof(tmpa));    memset(tmpb,0,sizeof(tmpb));    memset(c,0,sizeof(c));    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; --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])            break;    for(j=i; j<len; ++j)        ans=ans+(char)(c[j]+'0');    if(!flag)        ans='-'+ans;    return ans;}bool judge(string s)//判断s是否是回文数{    for(int i=0; i<s.length()/2; ++i)        if(s[0+i]!=s[s.length()-1-i])            return false;    return true;}string pow(int n)//10的n次方{    string s="1";    while(n--)        s+="0";    return s;}int main(){    ios::sync_with_stdio(false);    int t,k=0;    cin>>t;    while(++k<=t)    {        string str;        cin>>str;        int tot=0;        while(str.length()>1)        {            if(judge(str))//如果str为回文数            {                p[++tot].s=str;                str="0";                break;            }            if(str==pow(str.length()))//如果str为'1000000....'这种形式            {                p[++tot].s="1";                p[++tot].s=sub(str,"1");                str="0";                break;            }            string s="";            int mid=str.length()/2;            if(str.length()&1)//奇数长度            {                string ss;                for(int i=0; i<=mid; ++i)                    s+=str[i];                s=sub(s,"1");                ss=s;                for(int i=mid-1; ~i; --i)                    s+=ss[i];            }            else//偶数长度            {                if(str.length()==2&&str[0]=='1')//如果str最后为'1x'(x>0)这种形式                    s="11";                else                {                    for(int i=0; i<mid; ++i)                        s+=str[i];                    s=sub(s,"1");                    for(int i=mid-1; ~i; --i)                        s+=s[i];                }            }            str=sub(str,s);            p[++tot].s=s;        }        if(str!="0")            p[++tot].s=str;        cout<<"Case #"<<k<<":"<<endl;        cout<<tot<<endl;        for(int i=1; i<=tot; ++i)            cout<<p[i].s<<endl;    }    return 0;}
原创粉丝点击