题目:延迟的回文数 (20 分)
给定一个 k+1 位的正整数 N,写成 a?k?a1?? a?0?? 的形式,其中对所有 i 有 0 ≤ a?i?? < 10 且 a?k > 0。N 被称为一个回文数,当且仅当对所有 i 有 a?i?? = a?k ? ai?? 。零也被定义为一个回文数。
非回文数也可以通过一系列操作变出回文数。首先将该数字逆转,再将逆转数与该数相加,如果和还不是一个回文数,就重复这个逆转再相加的操作,直到一个回文数出现。如果一个非回文数可以变出回文数,就称这个数为延迟的回文数。(定义翻译自 https://en.wikipedia.org/wiki/Palindromic_number )
给定任意一个正整数,本题要求你找到其变出的那个回文数。
输入格式:
输入在一行中给出一个不超过1000位的正整数。
输出格式:
对给定的整数,一行一行输出其变出回文数的过程。每行格式如下
A + B = C
其中 A
是原始的数字,B
是 A
的逆转数,C
是它们的和。A
从输入的整数开始。重复操作直到 C 在 10 步以内变成回文数,这时在一行中输出 C is a palindromic number.
;或者如果 10 步都没能得到回文数,最后就在一行中输出 Not found in 10 iterations.
。
输入样例 1:
97152输出样例 1:
97152 + 25179 = 122331
122331 + 133221 = 255552
255552 is a palindromic number.
输入样例 2:
196输出样例 2:
196 + 691 = 887
887 + 788 = 1675
1675 + 5761 = 7436
7436 + 6347 = 13783
13783 + 38731 = 52514
52514 + 41525 = 94039
94039 + 93049 = 187088
187088 + 880781 = 1067869
1067869 + 9687601 = 10755470
10755470 + 07455701 = 18211171
Not found in 10 iterations.
题目分析及实现
这个题是有点麻烦的,尤其是很多容易犯错的地方
需要注意的是:
- 超长整数相加,数字很大,以字符串存储并计算,细节可参考这篇博客
- 最多判断十次,失败则输出Not found in 10 iterations.
- 中间步骤输出相加过程
- 这里因为是两个同长度的数相加,且高位对低位都是相同的,所以在计算的过程中不需要逆置来简化操作
这个题我做了好久好久,脑子总是有些混乱,小细节一定要考虑好,比如什么时候判出,什么时候判断就是回文数。
现在发现做题目,敲代码的时候一定要清楚地知道边界是什么,分界点找到了,就会简单很多,有时候卡题,大多数的测试点过不去都是由于分界点找的 不对 或者 不全 或者 实现方法不对。
继续努力。
//AC
import java.util.Scanner;public class Main {
private static boolean isP = true;// 回文数标记public static void main(String[] args) {
Scanner in = new Scanner(System.in);StringBuilder input = new StringBuilder(in.next());in.close();boolean find = false;// 判断十次是否找到Loop: for (int time = 0; time < 10; time++) {
isP(input);if (isP) {
System.out.println(input + " is a palindromic number.");find = true;break Loop;} elseinput = add(input);System.out.println(input);}if (!find)System.out.println("Not found in 10 iterations.");}// 大整数相加public static StringBuilder add(StringBuilder input) {
// 需要建立新的对象等于input,否则只是新建一个引用,原对象也变了StringBuilder B = new StringBuilder(input);B = B.reverse();System.out.print(input + " + " + B + " = ");int[] num = new int[B.length() + 1];// 1.把两个大整数用数组存储,已经逆置char[] charsA = B.toString().toCharArray();char[] charsB = input.toString().toCharArray();int[] result = new int[charsA.length + 1];// 2.遍历数组,按位相加for (int i = 0; i < result.length; i++) {
int temp = result[i];if (i < charsA.length) {
temp += charsA[i] - '0' + charsB[i] - '0';}// 判断是否进位if (temp >= 10) {
temp = temp - 10;result[i + 1] = 1;}result[i] = temp;}// 3.把result数组再次逆序并转成StringStringBuilder sb = new StringBuilder();// 判断最后一位是否发生了进位int head = result.length - 1;if (result[result.length - 1] == 0) {
head = result.length - 2;}for (int i = head; i >= 0; i--) {
sb.append(result[i]);}return input = new StringBuilder(sb.toString());}// 判断是否为回文数public static void isP(StringBuilder input) {
int time = 0;char a = 'c';char b = 'd';for (int i = 0; i < input.length() / 2; i++) {
time++;a = input.charAt(i);b = input.charAt(input.length() - 1 - i);if (a != b) {
isP = false;break;}}// 当a==b且遍历完的时候,可作为更改点if (time == input.length() / 2 && a == b)isP = true;}
}