您的位置:首页 > 其它

hdu 5920 Ugly Problem(构造题)

2017-10-05 20:52 302 查看

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: