牛牛的完美数问题

【题目描述】 对于一个十进制正整数 T , 如果 T 的每一位数字只可能是1、2、3中的其中一个 , 则称 T 是完美数。
例如 123、1、3321都是完美数 , 而5、1234则不是。
牛牛想写一个函数f(n) , 使得其返回最大的不大于n的完美数 , 请你帮助牛牛实现这个函数。
 

【如题所述】 f(100)=33; f(213)=213; f(3251)=3233; f(5120)=3333; f(2092)=1333; f(1099)=333; f(51099)=33333; f(3101)=2333 。

package com.cjh.demo;

import java.util.ArrayList;
import java.util.Scanner;

/**
 * @Description:
 * @Author:ChengJh
 * @Date 2023/03/15 13:59
 * @Version: v1.0
 **/
public class Test {

    /**
     * 题目描述:
     * 对于一个十进制正整数 T , 如果 T 的每一位数字只可能是1、2、3中的其中一个 , 则称 T 是完美数。
     * 例如 123、1、3321都是完美数 , 而5、1234则不是。
     * 牛牛想写一个函数f(n) , 使得其返回最大的不大于n的完美数 , 请你帮助牛牛实现这个函数。
     * <p>
     * 如题所述: f(100)=33; f(213)=213; f(3251)=3233; f(5120)=3333; f(2092)=1333; f(1099)=333; f(51099)=33333; f(3101)=2333 。
     */
    public static long getPerfectNum(long num) {
        if (num <= 0) {
            return -1;
        }
        long res = 0;
        // 个位放在最前面。
        ArrayList<Long> list = new ArrayList<>();
        while (num != 0) {
            list.add(num % 10);
            num /= 10;
        }
        for (int i = list.size() - 1; i >= 0; i--) {
            if (list.get(i) > 3) {
                // 若当前位的数字大于3的, 则当前位以及所有比其低的位都是按3处理。
                for (int j = i; j >= 0; j--) {
                    list.set(j, 3L);
                }
                break;
            } else if (list.get(i) == 0) {
                // 若当前位的数字等于0的, 则要跟其旁边的高位去借, 并且当前位以及所有比其低的位都是按3处理。
                for (int j = i + 1; j < list.size(); j++) {
                    if (list.get(j) > 1) {
                        list.set(j, (list.get(j) - 1));
                        break;
                    }
                    // list.get(j) 等于 1 的时候。
                    if (j < list.size() - 1) {
                        list.set(j, 3L);
                    } else {
                        list.set(j, 0L);
                    }
                }
                for (int j = i; j >= 0; j--) {
                    list.set(j, 3L);
                }
                break;
            }
        }
        for (int i = list.size() - 1; i >= 0; i--) {
            res = res * 10 + list.get(i);
        }
        return res;
    }

    public static long getPerfectNum2(long num) {
        if (num <= 0) {
            return -1;
        }
        String[] split = (num + "").split("");
        StringBuilder tempSB = new StringBuilder();
        for (int i = 0; i < split.length; i++) {
            if ("0".equals(split[i])) {
                // 若当前位的数字等于0的, 则要跟其旁边的高位去借, 并且当前位以及所有比其低的位都是按3处理。
                for (int j = i - 1; j >= 0; j--) {
                    if (false == "1".equals(split[j])) {
                        tempSB.replace(j, j + 1, (Integer.parseInt(split[j]) - 1) + "");
                        break;
                    }
                    // split[j] 等于 "1" 的时候。
                    if (j != 0) {
                        tempSB.replace(j, j + 1, "3");
                    } else {
                        tempSB.replace(j, j + 1, "0");
                    }
                }
                for (int j = i; j < split.length; j++) {
                    tempSB.append("3");
                }
                break;
            } else if ("1".equals(split[i]) || "2".equals(split[i]) || "3".equals(split[i])) {
                tempSB.append(split[i]);
            } else {
                // 若当前位的数字大于3的, 则当前位以及所有比其低的位都是按3处理。
                for (int j = i; j < split.length; j++) {
                    tempSB.append("3");
                }
                break;
            }
        }
        return Long.parseLong(tempSB.toString());
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入正整数的总个数(T): ");
        int T = scanner.nextInt();
        if (T <= 0) {
            System.out.println("\n程序提前结束。");
            return;
        }
        long[] arr = new long[T];
        long[] res = new long[T];
        long[] res2 = new long[T];
        for (int i = 0; i < T; i++) {
            System.out.print("请输入第" + (i + 1) + "个正整数: ");
            arr[i] = scanner.nextLong();
        }
        for (int i = 0; i < T; i++) {
            res[i] = getPerfectNum(arr[i]);
            res2[i] = getPerfectNum2(arr[i]);
        }
        for (int i = 0; i < T; i++) {
            System.out.println((i + 1) + " : " + arr[i] + " -> " + res[i] + " ~ " + res2[i]);
        }
        System.out.println("\n程序运行完毕。");
    }
}

特别鸣谢:完美数问题_resumebb的博客-CSDN博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值