题解 | #[NOIP1999]回文数#

[NOIP1999]回文数

https://www.nowcoder.com/practice/a432eb24b3534c27bdd1377869886ebb

public class Program {
    public static void Main() {
        /*
        1.难点是在于进行一次N进制的加法,这里我们不用转成十进制加完后再转回来
        2.不管题目输入的是几进制,我们都先转为数字存进数组里,然后把数组翻转,两个数组对应的位数相加
        3.相加后判断是否有进位,有进位就进位,然后取余数
        4.由于进制数M在100位以内,因此数组要考虑溢出的情况
        5.这里用数组而不用字符串的原因是假如输入的是十六进制,以字母A为例,字母A对应的数是10
        我们要把这个10存起来,如果用字符串再转成字符数组就会把10拆分成1和0,这样加起来的结果就不对

        示例1:N = 9,M = 87
        int [10000000]a = {8,7,0...0};
        int [10000000]b = {7,8,0...0};
        循环过程:
        a[1] + = b[1] = 15;   用15除以进制N判断是否有进位
        a[2] + = a[1] / N;       结果为1,即进位1
        a[1] % = N;           进位后原来的数取余数
        第一轮循环过后得出来的数为 671 step = 1;
        第二轮循环过后得出来的数为 758 step = 2
        第三轮循环过后得出来的数为 6271 step = 3;
        第四轮循环过后得出来的数为 7018 step = 4;
        第五轮循环过后得出来的数为 62161 step = 5;
        第六轮循环过后得出来的数为 78287 step = 6;
        */

        int N = int.Parse(System.Console.ReadLine());

        char[] M = System.Console.ReadLine().ToCharArray();
        int[] copy_M = new int[1000000];

        //有效数组长度,比如6710,则有效长度为4,下面循环时不用循环完整个数组长度
        int Len = M.Length;
        int copy_Len = Len;

        //把输入的字符转成数字存进数组
        for (int i = 0; i < M.Length; i++) {
            //如果是数字
            if (M[i] >= '0' && M[i] <= '9')
                copy_M[i] = M[i] - '0';
            //如果是字母
            else
                copy_M[i] = M[i] - 'A' + 10;
        }

        int STEP = 0;
        while (STEP < 30) {
            copy_Len = Len;
            //翻转数组copy_M
            int[] R_copy_M = new int[1000000];
            int tail = copy_Len - 1;
            for (int start = 0; start < copy_Len; start++) {
                R_copy_M[start] = copy_M[tail];
                tail--;
            }

            //翻转后将两个数组的对应位数相加
            Len = 0;
            int i;
            for ( i = 0; i < copy_Len; i++) {
                copy_M[i] += R_copy_M[i];
                //有进位就进位
                copy_M[i + 1] += copy_M[i] / N;
                //取余数
                copy_M[i] %= N;
                //记录有效长度
                Len += 1;
            }
            //循环完判断i位置是否为0,不为0说明进位了,则有效长度加1
            if (copy_M[i] != 0) {
                Len += 1;
            }
            STEP++;

            //判断是否为回文数
            int tail_Len = Len - 1;
            bool isNum = true;
            for (int j = 0; j < Len; j++) {
                if (copy_M[j] != copy_M[tail_Len]) {
                    isNum = false;
                    break;
                }
                if (tail_Len < Len / 2)
                    break;
                tail_Len--;
            }
            //是回文数退出循环
            if (isNum)
                break;
        }
        if (STEP < 30)
            System.Console.WriteLine("STEP=" + STEP);
        else
            System.Console.WriteLine("Impossible!");
    }
}

全部评论

相关推荐

02-15 22:29
门头沟学院 Java
点赞 评论 收藏
分享
神哥了不得:你简历字体有点不太协调呀,下面的字实在太小了呀,而且项目也不太行,建议换几个高质量的项目,面试会多很多
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务