ALGO-14 回文数
ALGO-14 回文数
题目
资源限制
时间限制:1.0s 内存限制:256.0MB
问题描述
若一个数(首位不为零)从左向右读与从右向左读都一样,我们就将其称之为回文数。
例如:给定一个 10 进制数 56,将 56 加 65(即把 56 从右向左读),得到 121 是一个回文数。
又如:对于 10 进制数 87:
STEP1:87+78 = 165 STEP2:165+561 = 726
STEP3:726+627 = 1353 STEP4:1353+3531 = 4884
在这里的一步是指进行了一次 N 进制的加法,上例最少用了 4 步得到回文数 4884。
写一个程序,给定一个 N(2<=N<=10 或 N=16)进制数 M(其中 16 进制数字为 0-9 与 A-F),求最少经过几步可以得到回文数。
如果在 30 步以内(包含 30 步)不可能得到回文数,则输出“Impossible!”
输入格式
两行,N 与 M
输出格式
如果能在 30 步以内得到回文数,输出“STEP=xx”(不含引号),其中 xx 是步数;否则输出一行”Impossible!”(不含引号)
样例输入
9
87
样例输出
STEP=6
题解
思路
用 int[]
存数字,判断回文、做运算方法可以通用。
- 先将 M 转换为 int[] 型的数字(两种情况)
- 判断是否回文
- 将数字翻转自加
- 重复 2,3
为什么不用 char[]
运算会麻烦一些,一不小心就会错。
Java
import java.util.Scanner;
public class ALGO_14 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int N = scanner.nextInt();
String M = scanner.next();
scanner.close();
System.out.println(palindrome(N, M));
}
private static String palindrome(int N, String M) {
int[] res;
if (N <= 10) {
res = form(Integer.valueOf(M).intValue());
} else {
res = form(M.toCharArray());
}
for (int i = 0; i <= 30; i++) {
if (isPalindromic(res))
return "STEP=" + i;
res = selfAdd(res, N);
}
return "Impossible!";
}
/**
* 模拟题目每一步的加法
* @param {int[]} num
* @param {int} scale
* @return 自加后的结果
*/
private static int[] selfAdd(int[] num, int scale) {
int[] rev = reverse(num);
int[] sum = new int[num.length + 1];
int rem = 0;
for (int i = num.length - 1; i >= 0; i--) {
int temp = num[i] + rev[i] + rem;
sum[i + 1] = temp % scale;
rem = temp / scale;
}
sum[0] = rem;
sum = normalize(sum);
return sum;
}
/**
* 反转数字
* @param {int[]} num
* @return 翻转后的数字
*/
private static int[] reverse(int[] num) {
int[] rev = new int[num.length];
for (int i = 0; i < rev.length; i++) {
rev[i] = num[num.length - 1 - i];
}
return rev;
}
/**
* 十以下的进制数字转换
* @param {int} num
* @return int[]型的数字
*/
private static int[] form(int num) {
int[] res = new int[Integer.toString(num).length()];
for (int i = 0; i < res.length; i++) {
res[i] = num % 10;
num /= 10;
}
return res;
}
/**
* 十以上的进制的数字转换
* @param {char} num
* @return int[]型的数字
*/
private static int[] form(char[] num) {
int[] res = new int[num.length];
for (int i = 0; i < num.length; i++) {
if (num[i] < '9' && num[i] > '0') {
res[i] = num[i] - '0';
} else {
res[i] = num[i] - 'A' + 10;
}
}
return res;
}
/**
* 判断是否为回文数
* @param {int[]} num
*/
private static boolean isPalindromic(int[] num) {
if (num.length == 0)
return false;
int left = 0, right = num.length - 1;
// NOTE: normal situation
while (left < right) {
if (num[left++] != num[right--])
return false;
}
return true;
}
/**
* 规范化数字:去除首位的0
* @param {int[]} num
* @return 首位非零的数字
*/
private static int[] normalize(int[] num) {
int[] result;
if (num[0] == 0) {
result = new int[num.length - 1];
for (int i = 0; i < result.length;) {
result[i] = num[++i];
}
} else {
result = num;
}
return result;
}
}