蓝桥练习


题目一

题目描述

平方末尾

能够表示为某个整数的平方的数字称为“平方数”

比如,25,64
虽然无法立即说出某个数是平方数,但经常可以断定某个数不是平方数。
因为平方数的末位只可能是:[0, 1, 4, 5, 6, 9] 这6个数字中的某个。
所以,4325435332必然不是平方数。

如果给你一个2位或2位以上的数字,你能根据末位的两位来断定它不是平方数吗?

请计算一下,一个2位以上的平方数的最后两位有多少种可能性?

注意:需要提交的是一个整数,表示2位以上的平方数最后两位的不同情况数。
不要填写任何多余内容(比如,说明解释文字等)

解题思路

  1. 这道题采用暴力遍历的方法,定义一个因子,因为是求两位以上的平方数,所以最低就用10来初始化因子,最大的范围就为10000(实际上最后求出的结果不需要1000就能测试完)。
  2. 定义int num;用来存储这个平方数。将这个平方数的后两位采用取模的方式num%100目的是保留最后两位。
  3. 将求模得到的最后两位放入到HashSet集合中,这里利用了Java中HashSet集合的特性用于去重。
  4. 最后通过set.size()得到最后的结果。

代码

import java.util.HashSet;
import java.util.Set;

public class Question01 {
    public static void main(String[] args) {
        /**
         * num = i * i
         */
        Set<String> set = new HashSet<>();
        for (int i = 10; i <= 10000; i++) {
            int num;
            num = i * i;
            String str = String.valueOf((num%100));
            set.add(str);
        }
        System.out.println(set.size());
    }
}

结果

22

题目二

题目描述

阶乘位数

9的阶乘等于:362880
它的二进制表示为:1011000100110000000
这个数字共有19位。

请你计算,9999 的阶乘的二进制表示一共有多少位?

注意:需要提交的是一个整数,不要填写任何无关内容(比如说明解释等)

解题思路

  1. 由于这题先求阶乘,而且都超出了java基本类型的值,就使用BigInteger来计算。
  2. 最后求得这个值bitLength()来计算二进制的长度。

代码

import java.math.BigInteger;
public class Question02 {
    public static void main(String[] args) {
        // BigInteger 传如的是String类型的
        BigInteger num = BigInteger.valueOf(1);

        for (int i = 9999; i > 1; i--) {

            num = num.multiply(BigInteger.valueOf(i));
        }
        System.out.println(num.bitLength());
    }
}

结果

118445

题目三

题目描述

标题:复数幂

设i为虚数单位。对于任意正整数n,(2+3i)n 的实部和虚部都是整数。
求 (2+3i)
123456 等于多少? 即(2+3i)的123456次幂,这个数字很大,要求精确表示。

答案写成 "实部±虚部i" 的形式,实部和虚部都是整数(不能用科学计数法表示),中间任何地方都不加空格,实部为正时前面不加正号。(2+3i)2 写成: -5+12i,
(2+3i)
5 的写成: 122-597i

注意:需要提交的是一个很庞大的复数,不要填写任何多余内容。

解题思路

本题与上面的题类似,都使用到了Big Integer来进行计算

采用循环的方式来进行计算。

代码

import java.math.BigInteger;
public class Question03 {
    public static void main(String[] args) {
        BigInteger a = new BigInteger("2");
        BigInteger b = new BigInteger("3");
        BigInteger c = new BigInteger("2");
        BigInteger d = new BigInteger("3");
        BigInteger m = null;
        BigInteger n = null;

        for (int i = 1; i <= 123456; i++) {
            m = a.multiply(c).subtract(d.multiply(d));
            n = a.multiply(d).add(b.multiply(c));
            a = m;
            b = n;
        }
        // 进行判断,设置符号
        System.out.println(m+"" + (n.compareTo(BigInteger.ZERO)<0?"":"+")+n+"i");

    }
}

题目四

题目描述

世纪末的星期
题目:
曾有邪教称1999年12月31日是世界末日。当然该谣言已经不攻自破。
还有人称今后的某个世纪末的12月31日,如果是星期一则会....
有趣的是,任何一个世纪末的年份的12月31日都不可能是星期一!!
于是,“谣言制造商”又修改为星期日......
1999年的12月31日是星期五,请问:未来哪一个离我们最近的一个世纪末年(即xx99年)的12月31日正好是星期天(即星期日)?

请回答该年份(只写这个4位整数,不要写12月31等多余信息)

解题思路

该题可以采用Java中的Calender类来进行解决,首先设置好初始的时间位置,也就是1999.12.31,但是需要注意的是英文中的时间月份是0表示1月,周天表示1。

每一个世纪(100年)进行循环,判断结束的条件是当前日期为周日,也就是week 为 1的时候跳出循环。

代码

import java.util.Calendar;
public class Question04 {
    public static void main(String[] args) {
        // 使用Java 的Calendar 来进行计算
        Calendar calendar = Calendar.getInstance();
        // 设置初始的日期
        calendar.set(1999,11,31);
        // 进行循环遍历
        for (int year = 1999; ;year+=100) {
            calendar.add(Calendar.YEAR,100);
            // 判断当前的这天是否是周日,也就是week 为 1,如果为1就跳出循环
            if (calendar.get(Calendar.DAY_OF_WEEK) == 1) {
                break;
            }
        }
        // 获取当前的年份
        System.out.println(calendar.get(Calendar.YEAR));
    }
}

题目五

题目描述

标题:三部排序

一般的排序有许多经典算法,如快速排序、希尔排序等。
但实际应用时,经常会或多或少有一些特殊的要求。我们没必要套用那些经典算法,可以根据实际情况建立更好的解法。
比如,对一个整型数组中的数字进行分类排序:
使得负数都靠左端,正数都靠右端,0在中部。注意问题的特点是:负数区域和正数区域内并不要求有序。可以利用这个特点通过1次线性扫描就结束战斗!!
以下的程序实现了该目标。
其中x指向待排序的整型数组,len是数组的长度。

static void sort(int[] x)
{
    int p = 0;
    int left = 0;
    int right = x.length-1;

    while(p<=right){
        if(x[p]<0){
            int t = x[left];
            x[left] = x[p];
            x[p] = t;
            left++;
            p++;
        }
        else if(x[p]>0){
            int t = x[right];
            x[right] = x[p];
            x[p] = t;
            right--;            
        }
        else{
            _________________________;  //代码填空位置 
        }
    }
}

如果给定数组:
25,18,-2,0,16,-5,33,21,0,19,-16,25,-3,0
则排序后为:
-3,-2,-16,-5,0,0,0,21,19,33,25,16,18,25

解题思路

1 通过已有的程序判断left right对应的意思是数组最小下表和最大的下标(字面意思)。

2 在while循环内的判断语句分别是x[p]<0x[p]>0、其他(也就是x[p]==0)这三种情况。

3 根据题目的要求小于0的数字需要在0的左边,大于需要在右边,从而可以根据这个过程判断p就是从左到右的游标,用于移动比较。

4 当p位置为0的时候就不需要移动了,就将p的位置进行右移最后得出p++

代码

public class Question05 {

    static void sort(int[] x)
    {
        int p = 0;
        // 初步判断应该是数组的left最小下标,right最大下表
        int left = 0;
        int right = x.length-1;
        
        
        // 当p的下标移动到和最大处就说明循环完毕了,就是结束条件
        while(p<=right){
            if(x[p]<0){
                // p位置上的值小于0,将
                int t = x[left];
                x[left] = x[p];
                x[p] = t;
                left++;
                p++;
            }
            else if(x[p]>0){
                // 将大于0的交换到右边
                int t = x[right];
                x[right] = x[p];
                x[p] = t;
                right--;
            }
            else{
//                _________________________;  //代码填空位置
                // 继续移动p下标
                p++;
            }
        }
    }
    public static void main(String[] args) {
        int[] arr = {25,18,-2,0,16,-5,33,21,0,19,-16,25,-3,0};
        sort(arr);
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
    }
}

Q.E.D.


一个在读大学生