蓝桥杯-练习-特殊回文数(JAVA)

package com.pb.structureAndalgorithm.sftg.test004;

import java.util.Scanner;

public class Main {

/*
    123321是一个非常特殊的数,它从左边读和从右边读是一样的。
  输入一个正整数n, 编程求所有这样的五位和六位十进制数,满足各位数字之和等于n 。
 */
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int n = input.nextInt();
        palindromeNumSplitIsEqN(10000, 99999, n, 100);
        palindromeNumSplitIsEqN(100000, 999999, n, 1100);
        input.close();
    }

    // 判断是否是回文, 辅助, 并不用到
    private static boolean isHui(int num) {

        String trim = String.valueOf(num).trim();
        int len = trim.length();
        String suffix = "";
        String prefix = "";
        int half = len / 2;

        if (len % 2 != 0) {
            suffix = trim.substring(0, half + 1);
        } else {
            suffix = trim.substring(0, half);
        }
        prefix = trim.substring(half);

        StringBuilder reversePrefix = new StringBuilder(prefix).reverse();

        if (reversePrefix.toString().equals(suffix)){
            return true;
        }

        return false;
    }

    // 是不是满足要求各个位数之和等于n
    private static boolean isEqToN(int num, int n){

        // 将整数转为字符串、去前后空格、再切分成一个一个字符
        String[] nums = String.valueOf(num).trim().split("");

        // 将各个字符求和
        int sum = 0;
        for (String v :
                nums) {
            sum += Integer.valueOf(v);
        }

        // 判断和是否等于这个n
        if (sum == n){
            return true;
        }
        return false;
    }

    // 一级步长100  二级步长110  三级步长11    (10000,99999)
    // 一级步长1100  二级步长110  三级步长11   (100000, 999999)
    // 参数: 1 起始数  2 结束数  3 n值  4 步长
    private static void palindromeNumSplitIsEqN(int start, int end,int n, int first){

        /*
             一级步长   10001 --> 10101 --> .... 10901  步长:100
             一级步长   100001 --> 101101 --> .... 109901  步长:1100

            10001 --> 10101 : 100    10101 --》 10201 : 100 ....
            同理


            二级步长   10901 --> 11011 --> ... 19091     109901 --> 110011 --> ... 190091  步长:110

            10901 --> 11011 : 110     20902 --> 22022 : 110
            109901 --> 110011 : 110  同理


            三级步长   19991 --> 20002 --> ... 90009     199991 --> 200002 --> ... 900009  步长:11

            19991 --> 20002 : 11     29992 --> 30003 : 11  .....
            199991 --> 200002 : 11   299992 --> 300003 : 11 .....
         */
        int firstStep = first;
        // 二级步长
        int twoStep = 110;
        // 三级步长
        int threeStep = 11;
        // 初始化
        int num = start + 1 - firstStep;
        // 每执行10次一级步长则二级步长加一, 每执行10次二级步长则三级步长加一   各个的次数
        int count1 = 0;
        int count2 = 0;
        // 对一级步长限制
        boolean flag = true;

        while (num < end){

            // 一级步长是否加10次了
            if (count1 == 10){

                // 二级步长增长
                num += twoStep;
                // 将一级步长次数置0
                count1 = 0;
                // 二级次数加一
                count2 ++;
                // 一级步长限制
                flag = false;

            }

            // 二级步长10次 三级步长增长
            if (count2 == 10){
                // 多加一次二级步长, 应减去
                num -= twoStep;
                // 三级步长增长
                num += threeStep;
                // 一级二级步长次数置0
                count1 = 0;
                count2 = 0;
            }

            // 一级步长限制限制增长
            if (flag){
                num += firstStep;
            }else{
                flag = true;
            }
            // 一级步长次数增长
            count1 ++;
            // 是否符合条件
            if(isEqToN(num, n)){
                System.out.println(num);
            }
        }

    }
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值