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≤10^1000).
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. Then 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
题目大意:给你一个不超过1000位的整数,将其分解成若干个回文数,总数不超过50个。
解题思路:取字符串的前一半,减一,翻转过去,大数减小数,循环上述过程直到小于20。
小于20的时候进行特判
12到19拆成 11 + x
11不动
10拆成 1 + 9
小于10不动
注意不要把”0“算进去
等于20的情况不需要特判,因为20还在while里面继续循环成11+9,然后9这个数才会从while里出来。
如: 9657932 取9657 变成9656 翻转为9656569 再用9657932-9656569 循环下去即可
AC代码:
1 import java.util.*; 2 import java.lang.Math; 3 import java.math.BigInteger; 4 public class Main{ 5 public static void main(String[] args){ 6 Scanner sc = new Scanner(System.in); 7 int t = sc.nextInt(); 8 String enter = sc.nextLine(); 9 BigInteger one = new BigInteger("1"); 10 BigInteger zero = new BigInteger("0"); 11 BigInteger twenty = new BigInteger("20"); 12 int k = 1; 13 while(t > 0){ 14 String in = sc.nextLine(); 15 int sum = 0; 16 String out[] = new String[50]; 17 int index = 0;int flag = 0; 18 BigInteger inn = new BigInteger(in); 19 while((inn.subtract(twenty)).compareTo(zero) != -1){ 20 if(in.length() % 2 == 1){ 21 int l = in.length(); 22 String sub = in.substring(0,l/2 + 1); 23 24 BigInteger bi = new BigInteger(sub); 25 bi = bi.subtract(one); 26 if((String.valueOf(bi)).length() != (l/2)+1){flag = 1;} 27 28 StringBuffer b1 = new StringBuffer(String.valueOf(bi)); 29 StringBuffer b2 = new StringBuffer(String.valueOf(bi)); 30 if(flag == 0){b2.deleteCharAt(l/2);flag = 0;} 31 32 b1 = b1.append(b2.reverse()); 33 out[index] = String.valueOf(b1);index ++;sum ++; 34 35 BigInteger tt = new BigInteger(String.valueOf(b1)); 36 inn = inn.subtract(tt); 37 in = String.valueOf(inn); 38 39 } 40 else{ 41 int l = in.length(); 42 String sub = in.substring(0,l/2); 43 44 BigInteger bi = new BigInteger(sub); 45 bi = bi.subtract(one); 46 StringBuffer b1 = new StringBuffer(String.valueOf(bi)); 47 StringBuffer b2 = new StringBuffer(String.valueOf(bi)); 48 b1 = b1.append(b2.reverse()); 49 out[index] = String.valueOf(b1);index ++;sum ++; 50 51 BigInteger tt = new BigInteger(String.valueOf(b1)); 52 inn = inn.subtract(tt); 53 in = String.valueOf(inn); 54 55 } 56 } 57 int last = Integer.valueOf(in); 58 if(last <= 19 && last >= 12){ 59 out[index] = "11";index ++; 60 int te = last - Integer.valueOf("11"); 61 out[index] = String.valueOf(te);index ++; 62 sum = sum + 2; 63 } 64 else if(last == 11){out[index] = "11";index ++;sum ++;} 65 else if(last == 10){out[index] = "9";index ++;out[index] = "1";index ++;sum = sum + 2;} 66 else if(last >= 1 && last <= 9){out[index] = String.valueOf(last);index ++;sum ++;} 67 System.out.println("Case #" + k + ":");System.out.println(sum); 68 for(int i = 0;i < index;i ++){ 69 System.out.println(out[i]); 70 } 71 k ++;t --; 72 } 73 } 74 }
一开始将题意理解为有10^1000那么长的字符串,以为用不了substring();浪费了好长时间。。。
奇数的if里面有个flag,是判断是不是取半后出现了10000-1=9999类似的情况,有的话就出大问题了。
偶数就没有这种问题,我试了下,1000 = 898 + 3 + 99,就不会是 999 + 1。。。
当然可以加上flag,却会更麻烦,因为偶数长度变成了奇数长度,还得删去一个字符再反转,所以没有加flag判断。。。
下面稍作讲解java大整数类(BigInteger类)以及StringBuffer在本题中出现的方法
BigInteger类:要使用 import java.math.BigInteger;
声明:大整数类不能像int型声明并赋初值(int i = 1;),要使用 BigInteger x = new BigInteger(str); 这种方法。
比较:大整数类也不能用符号比较,只能用类似比较字符串的方法来比较,如出现在19行的 while((inn.subtract(twenty)).compareTo(zero) != -1)
if(a.compareTo(b) == -1) => a < b
if(a.compareTo(b) == 0) => a == b
if(a.compareTo(b) == 1) => a > b
运算:
a.add(b) 大整数加法
a.subtract(b) 大整数减法
a.multiply(b) 大整数乘法
a.divide(b) 大整数除法(取整)
a.remainder(b) 大整数取模
StringBuffer类:
声明:和大整数类有些相似,在括号里放入初值 StringBuffer x = new StringBuffer(str); 但是StringBuffer无法使用‘+’这种运算符运算。
字符串反转: x.reverse();
字符串追加: x.append(str);
按索引删除字符: x.deleteCharAt(index);
要注意的是,这些StringBuffer的方法都会返回到本身,因此语句执行后,这个字符串就会改变。
我们用一个小的示例程序来说明:
1 import java.util.*; 2 3 public class Main{ 4 public static void main(String[] args){ 5 String str1 = "aaabbb"; 6 String str2 = str1 + "ccc"; 7 System.out.println("str1: " + str1); 8 System.out.println("str2: " + str2); 9 StringBuffer stb1 = new StringBuffer(str1); 10 StringBuffer stb2 = new StringBuffer(str1); 11 StringBuffer stb3 = new StringBuffer(str1); 12 stb2 = stb2.append(stb1.reverse()); 13 System.out.println("stb1: " + stb1); 14 System.out.println("stb2: " + stb2); 15 stb3 = stb3.append(stb1.deleteCharAt(2)); 16 System.out.println("stb1: " + stb1); 17 System.out.println("stb2: " + stb2); 18 System.out.println("stb3: " + stb3); 19 } 20 } 21 22 //output 23 24 //str1: aaabbb 25 //str2: aaabbbccc 26 27 //stb1: bbbaaa 28 //stb2: aaabbbbbbaaa 29 30 //stb1: bbaaa 31 //stb2: aaabbbbbbaaa 32 //stb3: aaabbbbbaaa
从示例中我们可以看出,进行操作后str1没有改动,但是stb1却一直发生变化。