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[] 存数字,判断回文、做运算方法可以通用。

  1. 先将 M 转换为 int[] 型的数字(两种情况)
  2. 判断是否回文
  3. 将数字翻转自加
  4. 重复 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;
    }
}

posted @ 2022-03-22 09:05  morning-start  阅读(40)  评论(0编辑  收藏  举报