7-6 又见最小回文数 (10 分)

  • Post author:
  • Post category:其他



7-6 又见最小回文数 (10 分)


若一个数正向看和反向看等价,则称做回文数。例如:6, 2552, 12321均是回文数。 给出一个非负整数n,求比n大的最小的回文数。

输入格式:

输入数据首先包含一个整数T(T<=150),表示测试实例的个数,然后是T行测试数据。 对于每组测试,输入一个非负整数n,n的总位数不超过10000,n不会有多余的前导0。

输出格式:

对于每组测试数据n。输出比n大的最小的回文数。

输入样例:

4
5
2543
12267
1111111111111111111111111

输出样例:

6
2552
12321
1111111111112111111111111

写了好久但是没过的。这个傻逼题有问题啊啊啊,网上搜的代码也过不到。温的痛



import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int T = scanner.nextInt();
        for (int w = 0; w < T; w++) {
            String num = scanner.next();
            StringBuffer sb = new StringBuffer();
            StringBuffer other_sb = new StringBuffer();
            scanner.nextLine();//吃回车
            //System.out.println(sb);
            //判断n的位数是奇数还是偶数
            if (num.length() % 2 == 0) {//偶数

                //如果该数本身是回文数
                if (isPalindrome(num)) {
                    sb.append(num.substring(0, num.length() / 2));//只取前半截
                    int len = sb.length();
                    int last = len - 1;//last指向最后一个字符的下标

                    while (last >= 0 && sb.charAt(last) - '0' + 1 == 10) {
                        sb.replace(last, last + 1, "0");
                        last--;

                    }
                    if (last == -1) {//以9999为例子,现在前半截为99 变成了 00.
                        sb.append(1);

                        sb.reverse();//导一下就可以
                        //现在是100
//                    String tem = String.valueOf(sb.reverse());
                        //sb.append(sb.reverse());//连接
                        char ch = sb.charAt(sb.length() - 1);//存中间位置
                        sb.deleteCharAt(sb.length() - 1);
                        String tem = String.valueOf(sb.reverse());//01
                        sb.reverse();//变回来//现在是10
                        sb.append(ch);//连接,100
                        sb.append(tem);
                        System.out.println(sb.toString());

                    } else {
                        sb.replace(last, last + 1, String.valueOf(sb.charAt(last) - '0' + 1));
                        String tem = String.valueOf(sb.reverse());
                        //sb.append(sb.reverse());//连接
                        sb.reverse();//导回来
                        sb.append(tem);//连接
                        System.out.println(sb.toString());
                    }

                } else {//不是回文数的偶数位


                    sb.append(num.substring(0, num.length() / 2));//前半截
                    other_sb.append(num.substring(num.length() / 2, num.length()));//后半截
                    int len = sb.length();
                    int last = len - 1;//last指向最后一个字符的下标

                    //前半截小于后半截。只需要将前半截最后一位加1,即可。例如num=2567.比较的时候前半截要翻一下
                    if (Integer.parseInt(sb.reverse().toString()) < Integer.parseInt(other_sb.toString())) {
                        sb.reverse();//倒回来
                        while (last >= 0 && sb.charAt(last) - '0' + 1 == 10) {
                            sb.replace(last, last + 1, "0");
                            last--;

                        }
                        if (last == -1) {//99 变成了 00.
                            sb.append(1);
                            sb.reverse();//导一下就可以

//                        String tem = String.valueOf(sb.reverse());
                            //sb.append(sb.reverse());//连接
                            sb.reverse();//导回来
                            sb.append(1);//连接
                            System.out.println(sb.toString());
                        } else {
                            sb.replace(last, last + 1, String.valueOf(sb.charAt(last) - '0' + 1));
                            String tem = String.valueOf(sb.reverse());
                            //sb.append(sb.reverse());//连接
                            sb.reverse();//导回来
                            sb.append(tem);//连接
                            System.out.println(sb.toString());
                        }


                    }
                    //前半截大于后半截。只需要将后半截变为前半截,即可。例如num=2543.比较的时候前半截要翻一下
                    else {

                        sb.reverse();//在比较完后先倒回来

                        String tem = String.valueOf(sb.reverse());
                        //sb.append(sb.reverse());//连接
                        sb.reverse();//导回来
                        sb.append(tem);//连接
                        System.out.println(sb.toString());
                    }
                    //}
                }
            } else {
                //是奇数位数
                //如果该数本身是回文数
                if (isPalindrome(num)) {
                    //例如:12321,前半截123 后半截21 .前半截+1,124加上后半截21,结果为12421
                    sb.append(num.substring(0, num.length() / 2 + 1));//前半截,最后一个字符是num中最中间的数
//                other_sb.append(num.substring(num.length() / 2+1, num.length()));//后半截
                    //是回文,只需要前半截将num中最中间的数加1即可。然后前半截加上后半截即可
                    int len = sb.length();
                    int last = len - 1;//last指向最后一个字符的下标

                    while (last >= 0 && sb.charAt(last) - '0' + 1 == 10) {
                        sb.replace(last, last + 1, "0");
                        last--;

                    }
                    if (last == -1) {//999 变成了 000.
                        sb.append(1);
                        sb.reverse();//导一下就可以 1000

                        char mid = sb.charAt(sb.length() - 1);//最中间的字符
                        sb.deleteCharAt(sb.length() - 1);//删除最中间的字符
                        String tem = String.valueOf(sb.reverse());
                        //sb.append(sb.reverse());//连接
                        sb.reverse();//导回来
                       // sb.append(mid);//加上中间的字符
                        sb.append(tem);//连接
                        System.out.println(sb.toString());
                    } else {
                        sb.replace(last, last + 1, String.valueOf(sb.charAt(last) - '0' + 1));

                        char mid = sb.charAt(sb.length() - 1);//最中间的字符
                        sb.deleteCharAt(sb.length() - 1);//删除最中间的字符
                        String tem = String.valueOf(sb.reverse());
                        //sb.append(sb.reverse());//连接
                        sb.reverse();//导回来
                        sb.append(mid);//加上中间的字符
                        sb.append(tem);//连接
                        System.out.println(sb.toString());
                    }

                } else {//不是回文数的奇数数位

                    sb.append(num.substring(0, num.length() / 2));//前半截,不含最中间的数
                    other_sb.append(num.substring(num.length() / 2 + 1, num.length()));//后半截,不含最中间的数
                    char mid = num.charAt(num.length() / 2);
                    int len = sb.length();
                    int last = len - 1;//last指向最后一个字符的下标

                    //前半截小于后半截。中间的数+1即可:12345,变为12412.比较的时候前半截要翻一下
                    if (Integer.parseInt(sb.reverse().toString()) < Integer.parseInt(other_sb.toString())) {


                        sb.reverse();//倒回来

                        sb.append(mid);//先将最中间的加上


                        //因为其长度要变化所以,要跟新其last
                        len = sb.length();
                        last = len - 1;//last指向最后一个字符的下标
                        while (last >= 0 && sb.charAt(last) - '0' + 1 == 10) {
                            sb.replace(last, last + 1, "0");
                            last--;

                        }
                        if (last == -1) {//99 变成了 00.
                            sb.append(1);
                            sb.reverse();//导一下就可以

                            char ch = sb.charAt(sb.length() - 1);//记录新的最后一位,即为最中间的
                            sb.deleteCharAt(sb.length() - 1);//删除最后一位
                            String tem = String.valueOf(sb.reverse());
                            //sb.append(sb.reverse());//连接
                            sb.reverse();//导回来
                            sb.append(ch);//加上中间的字符
                            sb.append(tem);//连接
                            System.out.println(sb.toString());
                        } else {
                            //只需要将后半截变成前半截即可。
                            sb.replace(last, last + 1, String.valueOf(sb.charAt(last) - '0' + 1));

                            char ch = sb.charAt(sb.length() - 1);//记录新的最后一位,即为最中间的
                            sb.deleteCharAt(sb.length() - 1);//删除最后一位
                            String tem = String.valueOf(sb.reverse());
                            //sb.append(sb.reverse());//连接
                            sb.reverse();//导回来
                            sb.append(ch);//加上中间的字符
                            sb.append(tem);//连接
                            System.out.println(sb.toString());
                        }


                    }
                    //前半截大于后半截。只需要将后半截变为前半截,即可。例如num=23314.比较的时候前半截要翻一下
                    else {

                        sb.reverse();//在比较完后先倒回来

                        String tem = String.valueOf(sb.reverse());
                        //sb.append(sb.reverse());//连接
                        sb.reverse();//导回来
                        sb.append(mid);//加上中间的字符
                        sb.append(tem);//连接
                        System.out.println(sb.toString());
                    }
                }
            }

        }
    }

    public static boolean isPalindrome(String s) {
        int n = s.length();
        for (int i = 0; i <= n / 2; i++) {//比较到一半即可
            if (s.charAt(i) != s.charAt(n - 1 - i)) {//找到对称的数不相等即返回false
                return false;
            }
        }
        return true;
    }

}



版权声明:本文为qq_46110320原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。