题意:将数字n转化成若干个回文数字之和。
知识点:大数减法 前缀0删除 字符串指针的应有
题解:因为带着完美主义的追求,把这题做傻了。。。
思路是对的,只是多考虑了些不必要的细节,导致本来简单的问题复杂化了,又被指针坑了一把。
所幸AC了,就贴出来当作对指针的回顾吧。
简洁解法: 将s的前半段s2取出来,然后s2-1,再构造成回文串c。s-=c,直到c=1。这么做简单不少,看来比赛时不能太追求完美,AC为王。
#include"bits/stdc++.h"
using namespace std;
const int N=1e3+100;
char *s,*small; //指向字符串的指针(为了快速删除前缀0而如此定义)
char ss[N],sm[N]; //给字符串指针 分配初始空间
void delete0(char * &ps) //删除前缀0
{
for(int i=0;i<strlen(ps);i++)
{
if(ps[i]!='0')
{
ps=&ps[i];
return ;
}
}
ps[0]=0;
}
void sub(int lens) //大数减法
{
delete0(s);
delete0(small);
bool flag=0;
int cha=strlen(s)-strlen(small);
for(int i=lens-1;i>=0;i--)
{
if(flag==1)
{
if(s[i]=='0')
s[i]='9';
else
s[i]=s[i]-1,flag=0;
}
if(i-cha<0)
break;
if(s[i]>=small[i-cha])
s[i]=s[i]-small[i-cha]+'0';
else
{
s[i]=s[i]+10-small[i-cha]+'0';
flag=1;
}
}
}
void find_s()
{
int lens=strlen(s);
if(lens%2==0)
{
if(s[lens/2-1]>=s[lens/2]) //中间左大于右 其实这不考率也行,毕竟n>50
{
int key;
for(int i=lens/2-1;i>=0;i--)
if(s[i]!='0') // 0特殊考虑
{
key=i;
break;
}
if(key==0)
{
small[0]='0';
for(int i=1;i<lens;i++)
{
small[i]='9';
}
return ;
}
for(int i=0;i<=key;i++)
{
small[i]=small[lens-i-1]=s[i];
if(i==key)
small[i]=small[lens-i-1]=s[i]-1;
}
for(int i=key+1;i<lens/2;i++)
small[i]=small[lens-i-1]='9';
}
else
{
for(int i=0;i<lens/2;i++)
small[i]=small[lens-i-1]=s[i];
}
}
else //lens奇数
{
if(lens==1)
{
small[0]=s[0];
return ;
}
if(s[(lens+1)/2-1]!='0')
{
for(int i=0;i<(lens+1)/2;i++)
{
small[i]=small[lens-i-1]=s[i];
if(i==(lens+1)/2-1)
small[i]=s[i]-1;
}
}
else ///和偶数时的处理一样
{
if(s[(lens+1)/2-2]>=s[(lens+1)/2]) //中间左大于右
{
int key;
for(int i=(lens+1)/2-2;i>=0;i--)
if(s[i]!='0')
{
key=i;
break;
}
if(key==0)
{
small[0]='0';
for(int i=1;i<lens;i++)
{
small[i]='9';
}
return ;
}
for(int i=0;i<=key;i++)
{
small[i]=small[lens-i-1]=s[i];
if(i==key)
small[i]=small[lens-i-1]=s[i]-1;
}
for(int i=key+1;i<(lens+1)/2;i++)
small[i]=small[lens-i-1]='9';
}
else
{
for(int i=0;i<lens/2;i++)
small[i]=small[lens-i-1]=s[i];
small[lens/2]='0';
}
}
}
}
char ans[60][N];
int main()
{
int t;
scanf("%d",&t);
for(int kase=1;kase<=t;kase++)
{
memset(ans,0,sizeof(ans));
scanf("%s",ss);
s=ss;
small=sm;
int lens,cnt=0;
while(true)
{
memset(sm,0,sizeof(sm));
small=sm; //small指针的初始化
delete0(s);
lens=strlen(s);
if(s[0]=='0'||lens==0)
break;
find_s();
delete0(small);
for(int i=0;i<strlen(small);i++)
ans[cnt][i]=small[i];
cnt++;
sub(lens);
}
printf("Case #%d:\n",kase);
printf("%d\n",cnt);
for(int i=0;i<cnt;i++)
printf("%s\n",ans[i]);
}
}
Ugly Problem
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 385 Accepted Submission(s): 145
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 1Hint9 + 9 = 18 999999999999 + 1 = 1000000000000
Source