PAT乙級——1079(大整數相加 迴文數判斷 邊界點)Java實現
阿新 • • 發佈:2018-12-10
題目:延遲的迴文數 (20 分)
給定一個 k+1 位的正整數 N,寫成 ak⋯a1 a0 的形式,其中對所有 i 有 0 ≤ ai < 10 且 ak > 0。N 被稱為一個迴文數,當且僅當對所有 i 有 ai = ak − 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;
} else
input = 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陣列再次逆序並轉成String
StringBuilder 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;
}
}