Java蓝桥杯刷题记录(二)


26.明码

题目描述

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

汉字的字形存在于字库中,即便在今天,1616 点阵的字库也仍然使用广泛。

1616 点阵的字库把每个汉字看成是 16 \times 1616×16 个像素信息。并把这些信息记录在字节中。

一个字节可以存储 88 位信息,用 3232 个字节就可以存一个汉字的字形了。 把每个字节转为 22 进制表示,11 表示墨迹,00 表示底色。每行 22 个字节,一共 1616 行,布局是:

    第 1 字节,第 2 字节
    第 3 字节,第 4 字节
    ....
    第 31 字节, 第 32 字节

这道题目是给你一段多个汉字组成的信息,每个汉字用 3232 个字节表示,这里给出了字节作为有符号整数的值。

题目的要求隐藏在这些信息中。你的任务是复原这些汉字的字形,从中看出题目的要求,并根据要求填写答案。

这段信息是(一共 1010 个汉字):

4 0 4 0 4 0 4 32 -1 -16 4 32 4 32 4 32 4 32 4 32 8 32 8 32 16 34 16 34 32 30 -64 0 
16 64 16 64 34 68 127 126 66 -124 67 4 66 4 66 -124 126 100 66 36 66 4 66 4 66 4 126 4 66 40 0 16 
4 0 4 0 4 0 4 32 -1 -16 4 32 4 32 4 32 4 32 4 32 8 32 8 32 16 34 16 34 32 30 -64 0 
0 -128 64 -128 48 -128 17 8 1 -4 2 8 8 80 16 64 32 64 -32 64 32 -96 32 -96 33 16 34 8 36 14 40 4 
4 0 3 0 1 0 0 4 -1 -2 4 0 4 16 7 -8 4 16 4 16 4 16 8 16 8 16 16 16 32 -96 64 64 
16 64 20 72 62 -4 73 32 5 16 1 0 63 -8 1 0 -1 -2 0 64 0 80 63 -8 8 64 4 64 1 64 0 -128 
0 16 63 -8 1 0 1 0 1 0 1 4 -1 -2 1 0 1 0 1 0 1 0 1 0 1 0 1 0 5 0 2 0 
2 0 2 0 7 -16 8 32 24 64 37 -128 2 -128 12 -128 113 -4 2 8 12 16 18 32 33 -64 1 0 14 0 112 0 
1 0 1 0 1 0 9 32 9 16 17 12 17 4 33 16 65 16 1 32 1 64 0 -128 1 0 2 0 12 0 112 0 
0 0 0 0 7 -16 24 24 48 12 56 12 0 56 0 -32 0 -64 0 -128 0 0 0 0 1 -128 3 -64 1 -128 0 0 

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 128M

代码

import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改

public class Main {
    public static void main(String[] args) {
        int array[] = new int[] {4, 0, 4, 0 ,4 ,0 ,4, 32, -1, -16, 4, 32, 4, 32, 4, 
                32, 4, 32, 4, 32, 8, 32, 8, 32, 16, 34, 16, 34, 32, 30, -64, 0, 
                16, 64, 16, 64, 34 ,68 ,127, 126 ,66 ,-124, 67, 4, 66, 4 ,66 ,-124, 
                126 ,100 ,66 ,36, 66, 4, 66, 4, 66, 4, 126, 4, 66, 40, 0 ,16,4,0,4,
                0,4,0,4,32,-1,-16,4,32,4,32,4,32,4,32,4,32,8,32,8,32,16,34,16,34,32,
                30,-64,0,0,-128,64,-128,48,-128,17,8,1,-4,2,8,8,80,16,64,32,64,-32,
                64,32,-96,32,-96,33,16,34,8,36,14,40,4,4,0,3,0,1,0,0,4,-1,-2,4,0,4,
                16,7,-8,4,16,4,16,4,16,8,16,8,16,16,16,32,-96,64,64,16,64,20,72,62,
                -4,73,32,5,16,1,0,63,-8,1,0,-1,-2,0,64,0,80,63,-8,8,64,4,64,1,64,0,
                -128,0,16,63,-8,1,0,1,0,1,0,1,4,-1,-2,1,0,1,0,1,0,1,0,1,0,1,0,1,0,5,
                0,2,0,2,0,2,0,7,-16,8,32,24,64,37,-128,2,-128,12,-128,113,-4,2,8,12,
                16,18,32,33,-64,1,0,14,0,112,0,1,0,1,0,1,0,9,32,9,16,17,12,17,4,33,
                16,65,16,1,32,1,64,0,-128,1,0,2,0,12,0,112,0,0,0,0,0,7,-16,24,24,48,
                12,56,12,0,56,0,-32,0,-64,0,-128,0,0,0,0,1,-128,3,-64,1,-128,0,0 };
        for(int i=0; i < array.length; i++) {
            if(array[i] < 0){
                String bin1 = Integer.toBinaryString(array[i]).substring(24).replace("0", " ");    //对负数,会用补码表示
                if(i % 2 != 0) System.out.println(bin1);    //起到换行作用
                else System.out.print(bin1);
            }else{
                String bin2 = Integer.toBinaryString(array[i]).replace("0", " ");
                String ary[] = new String[] {"       ","      ","     ","    ","   ","  "," ",""};
                if(i % 2 != 0) System.out.println(ary[bin2.length()-1]+bin2);
                else System.out.print(ary[bin2.length()-1]+bin2);
            }
        }
    }
}
法一
import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改

public class Main {
    public static void main(String[] args) {
        //存储由数字转换的二进制编码
        String[][] b=new String[16][2];
        //存储每个汉字的32位字节(数字)
        int [] []array=new int[16][2];
        //存储所给信息
        int [][][]c=new int[][][] {{{4, 0} ,{4, 0},{ 4, 0}, {4, 32},{ -1, -16},{ 4, 32},{ 4 ,32} ,{4 ,32},{ 4, 32},{ 4, 32},{ 8, 32},{ 8, 32},{ 16, 34}, {16, 34}, {32, 30}, {-64 ,0} },
 
                 {{16, 64},{ 16, 64},{ 34, 68},{ 127 ,126},{ 66, -124},{67, 4},{ 66, 4},{ 66 ,-124},{ 126, 100},{ 66, 36} ,{66 ,4 },{66, 4},{ 66, 4},{126 ,4} ,{66,40},{ 0, 16} },
 
                 {{4, 0} ,{4, 0},{ 4, 0}, {4, 32},{ -1, -16},{ 4, 32},{ 4 ,32} ,{4 ,32},{ 4, 32},{ 4, 32},{ 8, 32},{ 8, 32},{ 16, 34}, {16, 34}, {32, 30}, {-64 ,0} },
 
                 {{0 ,-128},{ 64, -128},{ 48, -128} ,{17, 8 },{1 ,-4} ,{2 ,8},{8, 80}, {16, 64}, {32, 64},{ -32, 64}, {32, -96},{32, -96},{ 33, 16} ,{34, 8}, {36, 14},{ 40, 4 }},
 
                 {{4, 0},{ 3 ,0} ,{1 ,0} ,{0 ,4} ,{-1, -2},{ 4, 0},{ 4, 16}, {7, -8},{ 4 ,16}, {4, 16},{4 ,16},{ 8 ,16} ,{8 ,16}, {16, 16},{ 32, -96}, {64, 64 }},
 
                 {{16, 64} ,{20, 72}, {62, -4}, {73 ,32} ,{5 ,16},{ 1 ,0} ,{63, -8} ,{1, 0},{ -1, -2}, {0, 64},{ 0, 80},{ 63 ,-8},{ 8 ,64} ,{4 ,64} ,{1 ,64}, {0, -128 }},
 
                 {{0, 16},{ 63, -8} ,{1 ,0} ,{1 ,0} ,{1 ,0} ,{1 ,4}, {-1, -2}, {1, 0 },{1 ,0} ,{1 ,0} ,{1 ,0}, {1, 0}, {1, 0},{ 1, 0},{ 5, 0},{ 2, 0 }},
 
                 {{2, 0},{ 2, 0}, {7, -16},{ 8, 32}, {24, 64}, {37, -128} ,{2 ,-128},{ 12 ,-128},{ 113, -4},{ 2, 8} ,{12 ,16}, {18, 32}, {33, -64} ,{1 ,0} ,{14 ,0},{ 112, 0 }},
 
                 {{1, 0} ,{1, 0}, {1, 0},{ 9 ,32},{ 9, 16}, {17, 12}, {17, 4},{ 33, 16},{ 65, 16},{ 1, 32}, {1, 64}, {0 ,-128},{ 1 ,0} ,{2 ,0} ,{12, 0}, {112, 0 }},
 
                 {{0, 0 },{0, 0}, {7, -16}, {24, 24}, {48, 12}, {56, 12},{ 0, 56},{ 0, -32}, {0, -64}, {0, -128 },{0,0},{0, 0},{ 1 ,-128},{ 3, -64}, {1 ,-128},{ 0, 0 }}};
        for (int m = 0; m < c.length; m++) //遍历所给信息
        {
            array=c[m];
            for (int i = 0; i < 16; i++) //遍历每个汉字的32位字节
            {
                for (int k = 0; k < 2; k++)
                {
                    b[i][k]=Integer.toBinaryString(array[i][k]);//把每位字节转换为二进制
                    if (b[i][k].length()<8) 
                    {
                        for (int j = 0; j < 8-b[i][k].length(); j++) 
                        {
                            System.out.print(0);//不满8位的用0补充
                        }
                        System.out.print(b[i][k]);//输出二进制字符串
                    }
                    else if (b[i][k].length()>8) 
                    {
                        System.out.print(b[i][k].substring(24));//输出最后8位
                    }
                    else 
                    {
                        System.out.print(b[i][k]);//输出二进制字符串
                    }
                }
                System.out.println();
                    
            }
            System.out.println("****************");//区分每个字
        }        
    }
}
法二
import java.math.BigDecimal;
import java.util.*;
public class test {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int flag = 0;
        while(scan.hasNext()){
            int value1 = scan.nextInt();
            int value2 = scan.nextInt();
            int [] arr1 = exchange(value1);
            int [] arr2 = exchange(value2);
            for (int i : arr1) {
                if(i==1){
                    System.out.print(""+i);
                }else{
                    System.out.print(" ");
                }

            }
            for (int i : arr2) {
                if(i==1){
                    System.out.print(""+i);
                }else{
                    System.out.print(" ");
                }
            }
            System.out.println();
            flag+=1;
            if(flag>=16&&flag%16==0){
                System.out.println("\n");
            }
        }
        scan.close();
    }
    //将数字转化为2进制的数
    private static int[] exchange(int value){
        int index=7;
        int arr[]=new int[8];
        Arrays.fill(arr, 0);
        int va = Math.abs(value);
        while(va!=0){
            arr[index] = va%2;
            index--;
            va/=2;
        }
        int flag=0;
        if(value<0){
            for(int i=7;i>=0;i--){
                if(flag==0&&arr[i]==1){
                    flag=1;
                }else{
                    arr[i] = 1-arr[i];
                }

            }
        }
        return arr;
    }

}
法三

参考

https://blog.csdn.net/m0_46598102/article/details/123339955

27.猜生日

题目描述

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

今年的植树节(20122012 年 33 月 1212 日),小明和他的叔叔还有小伙伴们一起去植树。休息的时候,小明的同学问他叔叔多大年纪,他叔叔说:“我说个题目,看你们谁先猜出来!”

“把我出生的年月日连起来拼成一个 88 位数(月、日不足两位前补 00)正好可以被今天的年、月、日整除!”

他想了想,又补充到:“再给个提示,我是 66 月出生的。”

根据这些信息,请你帮小明算一下,他叔叔的出生年月日。

格式是年月日连成的 88 位数。例如,如果是 19481948 年 66 月 1212 日,就写:1948061219480612。

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 128M

代码

import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改

public class Main {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        //在此输入您的代码...
        for(int i = 19000000; i <= 20000000; i++){
          if(i % 2012 == 0 && i % 3 == 0 && i % 12 == 0){
            String temp = i + "";
            int day = Integer.valueOf(temp.substring(6, 8));
            if(temp.charAt(5) == '6' && temp.charAt(4) == '0' && day <= 30){
              System.out.println(i);
              break;
            }
          }
        }
        scan.close();
    }
}
法一
/*
* 构建一个八位数就可以了
*
* year从2012年开始往后降
* day从1开始递增直到31
* 19550604答案正确
* */
import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改

public class Main {
   public static void main(String[] args) {
        int startYear = 2012;
        int startMonth = 6;
        int startDay = 12;
        for(int i=startYear;i>=0;i--){
            for(int j=1;j<=31;j++){
                //如果day不足10补0
                String dayStr = "";
                if(j<10){
                    dayStr = "0"+j;
                }else{
                    dayStr = j+"";
                }
                String monthStr = "06";
                String yearStr = i+"";
                //构建这个日期
                String dateStr = yearStr+monthStr+dayStr;
                //转化为int
                int date = Integer.parseInt(dateStr);
                if(date%startYear==0&&date%startMonth==0&&date%startDay==0){
                    System.out.println(dateStr);
                    return;
                }

            }
        }
    }
}
法二

28.数的分解

题目描述

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

把 20192019 分解成 33 个各不相同的正整数之和,并且要求每个正整数都不包含数字 22 和 44,一共有多少种不同的分解方法?

注意交换 33 个整数的顺序被视为同一种方法,例如 1000+1001+181000+1001+18 和 1001+1000+181001+1000+18 被视为同一种。

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 128M

代码

import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改

//数的分解
/*
 * 用2个for循环遍历数字,第3个数字为2019减前两个,要保证一个数比一个大,才能保证不会重。
 * 用一个方法判断每个数都不等于2和4;
 */

public class Main {
    public static void main(String[] args) {
        //个数
        int sum = 0;
        //要保证前面比后面一个数小,0不能包括
        for (int i = 1; i < 2019/2; i++) {
            for (int j = i+1; j < 2019; j++) {
                int k = 2019-i-j;
                //要保证不重复,不交换顺序,那么后面的要大于前面的
                if ((ik) ) {
                    //判断是否出现2和4
                    if (isF(i) && isF(j) && isF(k) ) {
                        sum++;
                    }
                }
            }
        }
        System.out.println(sum);
    }

    //判断是不是2和4的方法
    public static boolean isF(int n) {
        
        int x = n;
        while (true) {
            if (x%10==2 || x%10==4) {
                return false;
            }
            if (x < 10) {
                return true;
            }
            x = x/10;
        }
    }
}

29.迷宫

题目描述

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

下图给出了一个迷宫的平面图,其中标记为 11 的为障碍,标记为 00 的为可以通行的地方。

010000
000100
001001
110000

迷宫的入口为左上角,出口为右下角,在迷宫中,只能从一个位置走到这 个它的上、下、左、右四个方向之一。

对于上面的迷宫,从入口开始,可以按 DRRURRDDDR 的顺序通过迷宫, 一共 1010 步。其中 D、U、L、RDULR 分别表示向下、向上、向左、向右走。 对于下面这个更复杂的迷宫(3030 行 5050 列),请找出一种通过迷宫的方式,其使用的步数最少,在步数最少的前提下,请找出字典序最小的一个作为答案。

请注意在字典序中 DD<L<R<U。

01010101001011001001010110010110100100001000101010
00001000100000101010010000100000001001100110100101
01111011010010001000001101001011100011000000010000
01000000001010100011010000101000001010101011001011
00011111000000101000010010100010100000101100000000
11001000110101000010101100011010011010101011110111
00011011010101001001001010000001000101001110000000
10100000101000100110101010111110011000010000111010
00111000001010100001100010000001000101001100001001
11000110100001110010001001010101010101010001101000
00010000100100000101001010101110100010101010000101
11100100101001001000010000010101010100100100010100
00000010000000101011001111010001100000101010100011
10101010011100001000011000010110011110110100001000
10101010100001101010100101000010100000111011101001
10000000101100010000101100101101001011100000000100
10101001000000010100100001000100000100011110101001
00101001010101101001010100011010101101110000110101
11001010000100001100000010100101000001000111000010
00001000110000110101101000000100101001001000011101
10100101000101000000001110110010110101101010100001
00101000010000110101010000100010001001000100010101
10100001000110010001000010101001010101011111010010
00000100101000000110010100101001000001000000000010
11010000001001110111001001000011101001011011101000
00000110100010001000100000001000011101000000110011
10101000101000100010001111100010101001010000001000
10000010100101001010110000000100101010001011101000
00111100001000010000000110111000000001000000001011
10000001100111010111010001000110111010101101111000

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 256M

代码

import java.util.*;
//迷宫
/**
 * 广度优先遍历的作用:寻找到所有路径,但是只有最短的路径才会连通,这是因为dis[xx][yy]==0这一个条件的限定,换就好说就是只要这一点没有走过这个值就是0,
 * 而第一个经过这个点的路径,一定是最短的(层数最少)。经过了广度优先遍历,虽然已经“找到了”这条路径,但是对于我们来说,我们还是无法知道它的具体
 * 位置信息(每一个点的位置)。
 * 深度优先遍历的作用:就是进一步明确这条路径的信息,不连通的路径都会dis[x][y]==dis[xx][yy]+1这一条件被排除
 * **/
public class Main {
    private static String[] nn= {
                  "01010101001011001001010110010110100100001000101010",
                  "00001000100000101010010000100000001001100110100101",
                  "01111011010010001000001101001011100011000000010000",
                  "01000000001010100011010000101000001010101011001011",
                  "00011111000000101000010010100010100000101100000000",
                  "11001000110101000010101100011010011010101011110111",
                  "00011011010101001001001010000001000101001110000000",
                  "10100000101000100110101010111110011000010000111010",
                  "00111000001010100001100010000001000101001100001001",
                  "11000110100001110010001001010101010101010001101000",
                  "00010000100100000101001010101110100010101010000101",
                  "11100100101001001000010000010101010100100100010100",
                  "00000010000000101011001111010001100000101010100011",
                  "10101010011100001000011000010110011110110100001000",
                  "10101010100001101010100101000010100000111011101001",
                  "10000000101100010000101100101101001011100000000100",
                  "10101001000000010100100001000100000100011110101001",
                  "00101001010101101001010100011010101101110000110101",
                  "11001010000100001100000010100101000001000111000010",
                  "00001000110000110101101000000100101001001000011101",
                  "10100101000101000000001110110010110101101010100001",
                  "00101000010000110101010000100010001001000100010101",
                  "10100001000110010001000010101001010101011111010010",
                  "00000100101000000110010100101001000001000000000010",
                  "11010000001001110111001001000011101001011011101000",
                  "00000110100010001000100000001000011101000000110011",
                  "10101000101000100010001111100010101001010000001000",
                  "10000010100101001010110000000100101010001011101000",
                  "00111100001000010000000110111000000001000000001011",
                  "10000001100111010111010001000110111010101101111000"};
    private static char[][] tu=new char[30][50];
    private static int[][] dis=new int[30][50];
    private static int[][] step= {{1,0},{0,-1},{0,1},{-1,0}};
    private static char[] direction= {'D','L','R','U'};
//    保存经过的每一个点位置信息,采用(x)*m+y的公式表示(x,y);x,y从0开始,位置也是从来开始。m:大于最长边的随便一个数
//    起点:0;终点:29*50-49
    private static Queue location=new LinkedList();
//    广度优先遍历求每一个位置到终点的距离,并存放在dis中
//    广度优先遍历寻找所有从终点到起点的路线
    public static void bfs() {//x,y当前位置;
        int x,y;//当前位置坐标
        //不为空,继续循环
        while(!location.isEmpty()) {
            int l=location.poll();//获取当前位置的坐标
            x=l/50;//获取当前位置x
            y=l%50;//获取当前位置y
            for(int i=0;i<4;i++) {//探索四个方向
                int xx=x+step[i][0];
                int yy=y+step[i][1];
                if(xx>=0&&xx<30&&yy>=0&&yy<50&&tu[xx][yy]=='0'&&dis[xx][yy]==0) {
                    dis[xx][yy]=dis[x][y]+1;//当前位置的距离+1等于本次探索位置的距离
                    location.add(xx*50+yy);
                    if(xx==0&&yy==0) {
                        break;
                    }
                }
            }
            
        }
    }
//    深度优先遍历,从起点到终点
    public static String dfs() {
        dis[29][49]=0;
//        起点
        int x=0;
        int y=0;
        String route="";
        while(x!=29||y!=49) {
            for(int i=0;i<4;i++) {
                int xx=x+step[i][0];
                int yy=y+step[i][1];
                if(xx>=0&&xx<30&&yy>=0&&yy<50&&tu[xx][yy]=='0') {
                    if(dis[x][y]==dis[xx][yy]+1) {
                        x=xx;
                        y=yy;
                        route+=direction[i];
                        break;
                    }
                }
            }
        }
        return route;
    }
    
    public static void main(String[] args) {
        long num=0;
        for(int i=0;i<30;i++) {
            tu[i]=nn[i].toCharArray();
        }
        location.add(29*50+49);
        bfs();
        String route=dfs();
        System.out.println(route);
    }
}
法一
import java.util.*;
// 1:无需package
// 2: 类名必须Main, 不可修改

public class Main {
    static class Node{
        int x;
        int y;
        String str;
        public Node(int x , int y ,String str){
            this.x =x;
            this.y =y;
            this.str = str;
        }
    }

    static char[][]  graph = new char[30][50];
    static char[] path = {'D','L','R','U'};
    static int[] r = {0,-1,1,0};
    static int[] c = {1,0,0,-1};
    static int[][] visited = new int[30][50];


    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        for(int i=0;i<30;i++){
            graph[i]=sc.nextLine().toCharArray();
        }
        sc.close();
    LinkedList queue = new LinkedList<>();
    queue.add(new Node(0, 0, ""));
    visited[0][0] =1;
    String shunxv ="";
    while(!queue.isEmpty()){
        Node  t = queue.poll();
        int x1 = t.x;
        int y1 = t.y;
        String str1 = t.str;
        if(x1==29&&y1==49){
            shunxv = str1;
            break;
        }
        for(int i=0;i<4;i++){
            int x2= x1+c[i];
            int y2= y1+r[i];
            if(x2>=0&&x2<=29&&y2>=0&&y2<=49&&graph[x2][y2]=='0'&&visited[x2][y2]!=1){
                queue.add(new Node(x2, y2, str1+path[i]));
                visited[x2][y2]=1;
            }
        }
    }
    System.out.println(shunxv);
    }
}
法二

30.质数

题目描述

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

我们知道第一个质数是 22、第二个质数是 33、第三个质数是 55……

请你计算第 20192019 个质数是多少?

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 128M

代码

import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改

public class Main {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        //在此输入您的代码...
         int sum = 1;
    
     int num = 0;
     for (int i = 3; sum < 2019; i++) {
         int flag = 0;
        for (int j = 2; j < i; j++) {
            if (i % j == 0) {
                break;
            }
            if (j == i - 1) {
                flag = 1;
            }
        }
        
        if (flag == 1) {
            sum++;
        }
        if (sum == 2019) {
             num = i;
        }
    }
     System.out.println(num);
    
        scan.close();
    }
}

31.承压计算

题目描述

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

X 星球的高科技实验室中整齐地堆放着某批珍贵金属原料。

每块金属原料的外形、尺寸完全一致,但重量不同。 金属材料被严格地堆放成金字塔形。

                             7 
                            5 8 
                           7 8 8 
                          9 2 7 2 
                         8 1 4 9 1 
                        8 1 8 8 4 1 
                       7 9 6 1 4 5 4 
                      5 6 5 5 6 9 5 6 
                     5 5 4 7 9 3 5 5 1 
                    7 5 7 9 7 4 7 3 3 1 
                   4 6 4 5 5 8 8 3 2 4 3 
                  1 1 3 3 1 6 6 5 5 4 4 2 
                 9 9 9 2 1 9 1 9 2 9 5 7 9 
                4 3 3 7 7 9 3 6 1 3 8 8 3 7 
               3 6 8 1 5 3 9 5 8 3 8 1 8 3 3 
              8 3 2 3 3 5 5 8 5 4 2 8 6 7 6 9 
             8 1 8 1 8 4 6 2 2 1 7 9 4 2 3 3 4 
            2 8 4 2 2 9 9 2 8 3 4 9 6 3 9 4 6 9 
           7 9 7 4 9 7 6 6 2 8 9 4 1 8 1 7 2 1 6 
          9 2 8 6 4 2 7 9 5 4 1 2 5 1 7 3 9 8 3 3 
         5 2 1 6 7 9 3 2 8 9 5 5 6 6 6 2 1 8 7 9 9 
        6 7 1 8 8 7 5 3 6 5 4 7 3 4 6 7 8 1 3 2 7 4 
       2 2 6 3 5 3 4 9 2 4 5 7 6 6 3 2 7 2 4 8 5 5 4 
      7 4 4 5 8 3 3 8 1 8 6 3 2 1 6 2 6 4 6 3 8 2 9 6 
     1 2 4 1 3 3 5 3 4 9 6 3 8 6 5 9 1 5 3 2 6 8 8 5 3 
    2 2 7 9 3 3 2 8 6 9 8 4 4 9 5 8 2 6 3 4 8 4 9 3 8 8 
   7 7 7 9 7 5 2 7 9 2 5 1 9 2 6 5 3 9 3 5 7 3 5 4 2 8 9 
  7 7 6 6 8 7 5 5 8 2 4 7 7 4 7 2 6 9 2 1 8 2 9 8 5 7 3 6 
 5 9 4 5 5 7 5 5 6 3 5 3 9 5 8 9 5 4 1 2 6 1 4 3 5 3 2 4 1 
X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X 

其中的数字代表金属块的重量(计量单位较大)。 最下一层的 XX 代表 3030 台极高精度的电子秤。

假设每块原料的重量都十分精确地平均落在下方的两个金属块上, 最后,所有的金属块的重量都严格精确地平分落在最底层的电子秤上。

电子秤的计量单位很小,所以显示的数字很大。

工作人员发现,其中读数最小的电子秤的示数为:20864582312086458231

请你推算出:读数最大的电子秤的示数为多少?

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 128M

代码

import java.util.*;

// 1:无需package
// 2: 类名必须Main, 不可修改

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        double[][] grid = new double[30][30];
        for (int i = 0; i < 29; ++i) {
            for (int j = 0; j <= i; ++j) {
                grid[i][j] = sc.nextInt();
            }
        }
        
        for (int i = 1; i < 30; ++i) {
            for (int j = 0; j <= i; ++j) {
                if (j == 0) {
                    grid[i][j] += grid[i - 1][j] / 2;
                } else if (j == i) {
                    grid[i][j] += grid[i - 1][j - 1] / 2;
                } else {
                    grid[i][j] += grid[i - 1][j] / 2 + grid[i - 1][j - 1] / 2;
                }
            }
        }
        Arrays.sort(grid[29]);
        System.out.println(2086458231 / grid[29][0] * grid[29][29]);
        // sc.close();
    }
}

32.递增序列

题目描述

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

对于一个字母矩阵,我们称矩阵中的一个递增序列是指在矩阵中找到两个字母,它们在同一行,同一列,或者在同一 4545 度的斜线上,这两个字母从左向右看、或者从上向下看是递增的。

例如,如下矩阵中

LANN
QIAO

LN、LN、AN、AN、IO、AO、LQ、AI、NO、NO、AQ、IN、ANLNLNANANIOAOLQAINONOAQINAN 等 1313 个 递增序列。注意当两个字母是从左下到右上排列时,从左向右看和从上向下看 是不同的顺序。

对于下面的 3030 行 5050 列的矩阵,请问总共有多少个递增序列?

VLPWJVVNNZSWFGHSFRBCOIJTPYNEURPIGKQGPSXUGNELGRVZAG
SDLLOVGRTWEYZKKXNKIRWGZWXWRHKXFASATDWZAPZRNHTNNGQF
ZGUGXVQDQAEAHOQEADMWWXFBXECKAVIGPTKTTQFWSWPKRPSMGA
BDGMGYHAOPPRRHKYZCMFZEDELCALTBSWNTAODXYVHQNDASUFRL
YVYWQZUTEPFSFXLTZBMBQETXGXFUEBHGMJKBPNIHMYOELYZIKH
ZYZHSLTCGNANNXTUJGBYKUOJMGOGRDPKEUGVHNZJZHDUNRERBU
XFPTZKTPVQPJEMBHNTUBSMIYEGXNWQSBZMHMDRZZMJPZQTCWLR
ZNXOKBITTPSHEXWHZXFLWEMPZTBVNKNYSHCIQRIKQHFRAYWOPG
MHJKFYYBQSDPOVJICWWGGCOZSBGLSOXOFDAADZYEOBKDDTMQPA
VIDPIGELBYMEVQLASLQRUKMXSEWGHRSFVXOMHSJWWXHIBCGVIF
GWRFRFLHAMYWYZOIQODBIHHRIIMWJWJGYPFAHZZWJKRGOISUJC
EKQKKPNEYCBWOQHTYFHHQZRLFNDOVXTWASSQWXKBIVTKTUIASK
PEKNJFIVBKOZUEPPHIWLUBFUDWPIDRJKAZVJKPBRHCRMGNMFWW
CGZAXHXPDELTACGUWBXWNNZNDQYYCIQRJCULIEBQBLLMJEUSZP
RWHHQMBIJWTQPUFNAESPZHAQARNIDUCRYQAZMNVRVZUJOZUDGS
PFGAYBDEECHUXFUZIKAXYDFWJNSAOPJYWUIEJSCORRBVQHCHMR
JNVIPVEMQSHCCAXMWEFSYIGFPIXNIDXOTXTNBCHSHUZGKXFECL
YZBAIIOTWLREPZISBGJLQDALKZUKEQMKLDIPXJEPENEIPWFDLP
HBQKWJFLSEXVILKYPNSWUZLDCRTAYUUPEITQJEITZRQMMAQNLN
DQDJGOWMBFKAIGWEAJOISPFPLULIWVVALLIIHBGEZLGRHRCKGF
LXYPCVPNUKSWCCGXEYTEBAWRLWDWNHHNNNWQNIIBUCGUJYMRYW
CZDKISKUSBPFHVGSAVJBDMNPSDKFRXVVPLVAQUGVUJEXSZFGFQ
IYIJGISUANRAXTGQLAVFMQTICKQAHLEBGHAVOVVPEXIMLFWIYI
ZIIFSOPCMAWCBPKWZBUQPQLGSNIBFADUUJJHPAIUVVNWNWKDZB
HGTEEIISFGIUEUOWXVTPJDVACYQYFQUCXOXOSSMXLZDQESHXKP
FEBZHJAGIFGXSMRDKGONGELOALLSYDVILRWAPXXBPOOSWZNEAS
VJGMAOFLGYIFLJTEKDNIWHJAABCASFMAKIENSYIZZSLRSUIPCJ
BMQGMPDRCPGWKTPLOTAINXZAAJWCPUJHPOUYWNWHZAKCDMZDSR
RRARTVHZYYCEDXJQNQAINQVDJCZCZLCQWQQIKUYMYMOVMNCBVY
ABTCRRUXVGYLZILFLOFYVWFFBZNFWDZOADRDCLIRFKBFBHMAXX

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 128M

代码

import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改

public class Main {
    String str="VLPWJVVNNZSWFGHSFRBCOIJTPYNEURPIGKQGPSXUGNELGRVZAG" + 
            "SDLLOVGRTWEYZKKXNKIRWGZWXWRHKXFASATDWZAPZRNHTNNGQF" + 
            "ZGUGXVQDQAEAHOQEADMWWXFBXECKAVIGPTKTTQFWSWPKRPSMGA" + 
            "BDGMGYHAOPPRRHKYZCMFZEDELCALTBSWNTAODXYVHQNDASUFRL" + 
            "YVYWQZUTEPFSFXLTZBMBQETXGXFUEBHGMJKBPNIHMYOELYZIKH" + 
            "ZYZHSLTCGNANNXTUJGBYKUOJMGOGRDPKEUGVHNZJZHDUNRERBU" + 
            "XFPTZKTPVQPJEMBHNTUBSMIYEGXNWQSBZMHMDRZZMJPZQTCWLR" + 
            "ZNXOKBITTPSHEXWHZXFLWEMPZTBVNKNYSHCIQRIKQHFRAYWOPG" + 
            "MHJKFYYBQSDPOVJICWWGGCOZSBGLSOXOFDAADZYEOBKDDTMQPA" + 
            "VIDPIGELBYMEVQLASLQRUKMXSEWGHRSFVXOMHSJWWXHIBCGVIF" + 
            "GWRFRFLHAMYWYZOIQODBIHHRIIMWJWJGYPFAHZZWJKRGOISUJC" + 
            "EKQKKPNEYCBWOQHTYFHHQZRLFNDOVXTWASSQWXKBIVTKTUIASK" + 
            "PEKNJFIVBKOZUEPPHIWLUBFUDWPIDRJKAZVJKPBRHCRMGNMFWW" + 
            "CGZAXHXPDELTACGUWBXWNNZNDQYYCIQRJCULIEBQBLLMJEUSZP" + 
            "RWHHQMBIJWTQPUFNAESPZHAQARNIDUCRYQAZMNVRVZUJOZUDGS" + 
            "PFGAYBDEECHUXFUZIKAXYDFWJNSAOPJYWUIEJSCORRBVQHCHMR" + 
            "JNVIPVEMQSHCCAXMWEFSYIGFPIXNIDXOTXTNBCHSHUZGKXFECL" + 
            "YZBAIIOTWLREPZISBGJLQDALKZUKEQMKLDIPXJEPENEIPWFDLP" + 
            "HBQKWJFLSEXVILKYPNSWUZLDCRTAYUUPEITQJEITZRQMMAQNLN" + 
            "DQDJGOWMBFKAIGWEAJOISPFPLULIWVVALLIIHBGEZLGRHRCKGF" + 
            "LXYPCVPNUKSWCCGXEYTEBAWRLWDWNHHNNNWQNIIBUCGUJYMRYW" + 
            "CZDKISKUSBPFHVGSAVJBDMNPSDKFRXVVPLVAQUGVUJEXSZFGFQ" + 
            "IYIJGISUANRAXTGQLAVFMQTICKQAHLEBGHAVOVVPEXIMLFWIYI" + 
            "ZIIFSOPCMAWCBPKWZBUQPQLGSNIBFADUUJJHPAIUVVNWNWKDZB" + 
            "HGTEEIISFGIUEUOWXVTPJDVACYQYFQUCXOXOSSMXLZDQESHXKP" + 
            "FEBZHJAGIFGXSMRDKGONGELOALLSYDVILRWAPXXBPOOSWZNEAS" + 
            "VJGMAOFLGYIFLJTEKDNIWHJAABCASFMAKIENSYIZZSLRSUIPCJ" + 
            "BMQGMPDRCPGWKTPLOTAINXZAAJWCPUJHPOUYWNWHZAKCDMZDSR" + 
            "RRARTVHZYYCEDXJQNQAINQVDJCZCZLCQWQQIKUYMYMOVMNCBVY" + 
            "ABTCRRUXVGYLZILFLOFYVWFFBZNFWDZOADRDCLIRFKBFBHMAXX";
    char[][] c=new char[30][50];
    int count=0;
    public Main() {
        for(int i=0;i) {
            for(int j=0;j) {
                c[i][j]=str.charAt(i*c[i].length+j);    
            }
        }
        for(int i=0;i) {
            for(int j=0;j) {
                check(i, j);
            }
        }
        System.out.println(count);
    }
    public void check(int i,int j) {
        //
        for(int k=1;k) {
            if(j+kk]) {
                count++;
            }
        }
        //
        for(int k=1;k) {
            if(i+kk][j]) {
                count++;
            }
        }
        //右下角
        for(int k=1;k) {
            if(i+kk]) {
                count++;
            }
        }
        //右上角
        for(int k=1;k) {
            if(i-k>=0&&j+kk]) {
                count++;
            }
        }
        //左下角
        for(int k=1;k) {
            if(i+k=0&&c[i][j]k]) {
                count++;
            }
        }
    }

    public static void main(String[] args) {
        new Main();
    }
}
法一
import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改

public class Main {
    public static int n=30,m=50;
    public static String s[]={
            "VLPWJVVNNZSWFGHSFRBCOIJTPYNEURPIGKQGPSXUGNELGRVZAG",
            "SDLLOVGRTWEYZKKXNKIRWGZWXWRHKXFASATDWZAPZRNHTNNGQF",
            "ZGUGXVQDQAEAHOQEADMWWXFBXECKAVIGPTKTTQFWSWPKRPSMGA",
            "BDGMGYHAOPPRRHKYZCMFZEDELCALTBSWNTAODXYVHQNDASUFRL",
            "YVYWQZUTEPFSFXLTZBMBQETXGXFUEBHGMJKBPNIHMYOELYZIKH",
            "ZYZHSLTCGNANNXTUJGBYKUOJMGOGRDPKEUGVHNZJZHDUNRERBU",
            "XFPTZKTPVQPJEMBHNTUBSMIYEGXNWQSBZMHMDRZZMJPZQTCWLR",
            "ZNXOKBITTPSHEXWHZXFLWEMPZTBVNKNYSHCIQRIKQHFRAYWOPG",
            "MHJKFYYBQSDPOVJICWWGGCOZSBGLSOXOFDAADZYEOBKDDTMQPA",
            "VIDPIGELBYMEVQLASLQRUKMXSEWGHRSFVXOMHSJWWXHIBCGVIF",
            "GWRFRFLHAMYWYZOIQODBIHHRIIMWJWJGYPFAHZZWJKRGOISUJC",
            "EKQKKPNEYCBWOQHTYFHHQZRLFNDOVXTWASSQWXKBIVTKTUIASK",
            "PEKNJFIVBKOZUEPPHIWLUBFUDWPIDRJKAZVJKPBRHCRMGNMFWW",
            "CGZAXHXPDELTACGUWBXWNNZNDQYYCIQRJCULIEBQBLLMJEUSZP",
            "RWHHQMBIJWTQPUFNAESPZHAQARNIDUCRYQAZMNVRVZUJOZUDGS",
            "PFGAYBDEECHUXFUZIKAXYDFWJNSAOPJYWUIEJSCORRBVQHCHMR",
            "JNVIPVEMQSHCCAXMWEFSYIGFPIXNIDXOTXTNBCHSHUZGKXFECL",
            "YZBAIIOTWLREPZISBGJLQDALKZUKEQMKLDIPXJEPENEIPWFDLP",
            "HBQKWJFLSEXVILKYPNSWUZLDCRTAYUUPEITQJEITZRQMMAQNLN",
            "DQDJGOWMBFKAIGWEAJOISPFPLULIWVVALLIIHBGEZLGRHRCKGF",
            "LXYPCVPNUKSWCCGXEYTEBAWRLWDWNHHNNNWQNIIBUCGUJYMRYW",
            "CZDKISKUSBPFHVGSAVJBDMNPSDKFRXVVPLVAQUGVUJEXSZFGFQ",
            "IYIJGISUANRAXTGQLAVFMQTICKQAHLEBGHAVOVVPEXIMLFWIYI",
            "ZIIFSOPCMAWCBPKWZBUQPQLGSNIBFADUUJJHPAIUVVNWNWKDZB",
            "HGTEEIISFGIUEUOWXVTPJDVACYQYFQUCXOXOSSMXLZDQESHXKP",
            "FEBZHJAGIFGXSMRDKGONGELOALLSYDVILRWAPXXBPOOSWZNEAS",
            "VJGMAOFLGYIFLJTEKDNIWHJAABCASFMAKIENSYIZZSLRSUIPCJ",
            "BMQGMPDRCPGWKTPLOTAINXZAAJWCPUJHPOUYWNWHZAKCDMZDSR",
            "RRARTVHZYYCEDXJQNQAINQVDJCZCZLCQWQQIKUYMYMOVMNCBVY",
            "ABTCRRUXVGYLZILFLOFYVWFFBZNFWDZOADRDCLIRFKBFBHMAXX"
    };
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        int ans=0;
        char c[][]=new char [n][m];
        for(int i=0;i){
            c[i]=s[i].toCharArray();
        }
        
        for(int i=0;i){
            for(int j=0;j){
                for(int k=1;k){
                    if(j+k//c[i]为列数   j+k为列
//                        System.out.println(c[i][j]+""+c[i][j+k]);
                        ans++;
                    }
                    if(i+k//c为行数   i+k为行
//                        System.out.println(c[i][j]+""+c[i+k][j]);
                        ans++;
                    }
                    if(j+k//元素的右下
//                        System.out.println(c[i][j]+""+c[i+k][j+k]);
                        ans++;
                    }
                    if(j+k=0&&c[i][j]!=c[i-k][j+k]){//元素的右上
//                        System.out.println(c[i][j]+""+c[i-k][j+k]);
                        ans++;
                    }
                }
            }
        }
        
        System.out.println(ans);
    }
}
法二

33.最大降雨量

题目描述

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

由于沙之国长年干旱,法师小明准备施展自己的一个神秘法术来求雨。

这个法术需要用到他手中的 4949 张法术符,上面分别写着 11 至 4949 这 4949 个数字。法术一共持续 77 周,每天小明都要使用一张法术符,法术符不能重复使用。

每周,小明施展法术产生的能量为这周 77 张法术符上数字的中位数。法术 施展完 77 周后,求雨将获得成功,降雨量为 77 周能量的中位数。

由于干旱太久,小明希望这次求雨的降雨量尽可能大,请大最大值是多少?

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 128M

代码

import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改

public class Main {
    public static void main(String[] args) {
        /*
        * [][][][a][][][]
        * [][][][b][][][]
        * [][][][c][][][]
        * [][][][max][][][]
        * [][][][d][][][]
        * [][][][e][][][]
        * [][][][f][][][]
        * 
        * 此题意思为将49分为7组数字,求取七组数字中每组数字的中位数所构成的数列的中位数的最大值
        * 即如图所示,最大化[max]
        * 49个数字中需要比[max]大的有【max】行的后三位,d、e、f行的后四位
        * 即结果如下
        * */
        System.out.println(49 - (3 * 4) - 3);
    }
}

34.奇数倍数

题目描述

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

请你找到最小的整数 XX 同时满足:

  1. XX 是 20192019 的整倍数;
  2. XX 的每一位数字都是奇数。

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 128M

代码

import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改

public class Main {
    public static boolean is(int n){//判断n的每位是不是都为奇数
      while(n>0){
        if(n%2==0) return false;
        n/=10;
      }
      return true;
    }
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        //在此输入您的代码...
        for(int i=1;;i++){
          if(!is(i)) continue;
          if(i%2019==0){
             System.out.println(i);//输出第一个满足的答案
             break;
          }
          
        }
        scan.close();
    }
}

35.路径

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

小蓝学习了最短路径之后特别高兴,他定义了一个特别的图,希望找到图 中的最短路径。

小蓝的图由 2021 个结点组成,依次编号 1 至 2021。

对于两个不同的结点 a, b,如果 a 和 b 的差的绝对值大于 21,则两个结点 之间没有边相连;如果 a 和 b 的差的绝对值小于等于 21,则两个点之间有一条 长度为 a 和 b 的最小公倍数的无向边相连。

例如:结点 1 和结点 23 之间没有边相连;结点 3 和结点 24 之间有一条无 向边,长度为 24;结点 15 和结点 25 之间有一条无向边,长度为 75。

请计算,结点 1 和结点 2021 之间的最短路径长度是多少。

提示:建议使用计算机编程解决问题。

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 128M

代码

import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改

public class Main {
    public static void main(String[] args) {
        int n = 2022 ;
        int[] q = new int[n] ;
        q[1] = 0 ;
        for (int i =2; i<= 2021; i++) {
            q[i]= Integer.MAX_VALUE ;
        }
        //dp  
        //当前q[j] 表示 从 1~j的最短距离
        //q[j] 可以是 当前 1~j的最短距离 或者 前一状态 到 该点的最短距离
        for (int i = 1; i<= 2020; i++ )
            for (int j= i+1 ; j<=2021 && (j-i<=21); j++) {
                q[j] = Math.min(q[j], q[i] + le(i, j) ) ;
            }
            
        System.out.println(q[2021]) ;
    }
    
    public static int gcd(int a, int b ) {
        return b !=0 ? gcd(b, a%b): a ; 
    }
    
    public static int le(int a, int b) {
        return a*b/gcd(a,b) ;
    }
}
法一
import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改

public class Main {
    public static void main(String[] args) {
        int[] r = new int[2022];
        for(int i = 2; i < 2022; i ++){
            r[i] = findMinRoute(i, r);
        }
        System.out.println(r[2021]);
    }
    static int findMinRoute(int pos, int[] r){
        int minRoute = Integer.MAX_VALUE;
        for(int i = pos - 1; pos - i <=21 && i > 0; i--){
            int len = lcm(pos, i);
            minRoute = Math.min(minRoute, len + r[i]);
        }
        return minRoute;
    }
    static int gcd(int a, int b) {
        return b == 0 ? a : gcd(b, a % b);
    }

    static int lcm(int a, int b) {
        return a * b / gcd(a, b);
    }
}
法二
import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改

public class Main {
    static final int n = 2021;
    //求ab之间的最小公约数
    static int gcd(int a,int b){
        return b == 0 ? a : gcd(b,a%b);
    }
    //求ab之间的最小公倍数
    static int lcm(int a,int b){
        return a * b / gcd(a,b);
    }

    public static void main(String[] args) {
        //记录两点之间的边长,初始值都为零,如果数组某点未变化则说明两点之间没有边长
        int[][] floyd = new int[n][n];
        for (int i = 0; i < n; i++) {
            for (int j = i+1; j < n && j < i+22 ; j++) {
                //根据题意可知两点之间的边长相等且等于最小公倍数,如果两点之间的差值大于21,两点间没有边长
                floyd[i][j] = floyd[j][i] = lcm(i+1,j+1);
            }
        }
        //弗洛伊德算法
        for (int k = 0; k < n; k++) {
            //中介点为k
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < n; j++) {
                    //(i和k、k和j之间的边长不为零且(i和j之间没有边长或者通过中介点k,i到k,k到j的距离之和小于i到j的距离))成立则替换i到j的距离
                    if(floyd[i][k] != 0 && floyd[k][j] != 0 && (floyd[i][j] == 0 || floyd[i][k] + floyd[k][j] < floyd[i][j]))
                        floyd[i][j] = floyd[i][k] + floyd[k][j];
                }
            }
        }
        //经过循环后,找出数组存储1到点2021之间的数据,该数据则为最短距离。
        System.out.println(floyd[0][n-1]);
    }
}
法三:floyd(会超时,但结果正确)

参考

https://python.iitter.com/other/309114.html

36.等差数列

题目描述

数学老师给小明出了一道等差数列求和的题目。但是粗心的小明忘记了一 部分的数列,只记得其中 NN 个整数。

现在给出这 NN 个整数,小明想知道包含这 NN 个整数的最短的等差数列有几项?

输入描述

输入的第一行包含一个整数 NN。

第二行包含 NN 个整数 A_1,A_2,··· ,A_NA1?,A2?,???,AN?。(注意 A_1A1? ~ A_NAN? 并不一定是按等差数列中的顺序给出)

其中,2 \leq N \leq 10^5,0 \leq A_i \leq 10^92N1050Ai?109。

输出描述

输出一个整数表示答案。

输入输出样例

示例

输入

5
2 6 4 10 20

输出

10

样例说明: 包含 2、6、4、10、20 的最短的等差数列是 2、4、6、8、10、12、14、16、 18、20。

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 256M

代码

import java.util.Scanner;
import java.util.Arrays;

// 1:无需package
// 2: 类名必须Main, 不可修改

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] nums = new int[n];
        for (int i = 0; i < n; i++) {
            nums[i] = sc.nextInt();
        }
        Arrays.sort(nums);
        int min = Integer.MAX_VALUE;
        for (int i = 1 ; i < n ;i++){
            if (nums[i] - nums[i - 1] < min){
                min = nums[i] - nums[i - 1];
            }
        }
        if (min == 0){
          System.out.println(n);
          return;
        }
        int res = (nums[n - 1] - nums[0]) / min + 1;
        System.out.println(res);
        sc.close();
    }
}

37.字串排序

题目描述

小蓝最近学习了一些排序算法,其中冒泡排序让他印象深刻。

在冒泡排序中,每次只能交换相邻的两个元素。

小蓝发现,如果对一个字符串中的字符排序,只允许交换相邻的两个字符,在所有可能的排序方案中,冒泡排序的总交换次数是最少的。

例如,对于字符串 lan 排序,只需要 1 次交换。对于字符串 qiao 排序,总共需要 4 次交换。

小蓝的幸运数字是 VV,他想找到一个只包含小写英文字母的字符串,对这个串中的字符进行冒泡排序,正好需要 VV 次交换。请帮助小蓝找一个这样的字符串。如果可能找到多个,请告诉小蓝最短的那个。如果最短的仍然有多个,请告诉小蓝字典序最小的那个。请注意字符串中可以包含相同的字符。

输入描述

输入一行包含一个整数 V\ (1 \leq V \leq 10^4)V (1V104),为小蓝的幸运数字。

输出描述

输出一个字符串,为所求的答案。

输入输出样例

示例 1

输入

4

输出

bbaa

示例 2

输入

100

输出

jihgfeeddccbbaa

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 256M

代码

package test;
import java.util.Scanner;

public class 字串排序 {
    static int[] pre = new int[300];// 前缀
    static int[] suf = new int[30];// 后缀
    static int num;
    static int l = 1;

    public static void main(String[] args) {
        Scanner cin = new Scanner(System.in);
        num = cin.nextInt();
        while (renum() < num) {// 获取最短字串长
            ++l;
            MaxStr(l);
        }
        getans(num, l);// 获得目标字串
        for (int i = 0; pre[i] != 0; i++) {
            System.out.print((char) pre[i]);
        }

    }

    public static int renum() {// 计算逆序数
        int cnt = 0;
        for (int i = 0; pre[i] != 0; ++i) {
            for (int j = i; pre[j] != 0; ++j) {
                if (pre[i] > pre[j]) {
                    ++cnt;
                }
            }
        }
        for (int i = 0; pre[i] != 0; ++i) {
            for (int j = 25; j >= 0; --j) {
                if (pre[i] - 'a' > j) {
                    cnt += suf[j];
                }
            }
        }
        int temp = 0;
        for (int i = 0; i < 26; ++i) {
            cnt += temp * suf[i];
            temp += suf[i];
        }
        return cnt;
    }

    public static void MaxStr(int l) {// 获取前缀确定且长度确定的前提下的最大逆序数字串
        reset();
        for (int i = 0; pre[i] != 0; ++i, --l)
            ;
        while (l > 0) {
            set();
            --l;
        }
    }

    public static void reset() {// 清除后缀
        int i = 0;
        while (i < 26 && suf[i] != 0) {
            suf[i] = 0;
            ++i;
        }
    }

    public static void set() {// 在后部序列中插入元素,保证逆序数最大
        int max = 0, temp = 0, index = 0;
        for (int i = 0; i < 26; ++i) {
            suf[i]++;
            if ((temp = getRe(i)) > max) {// 找出使逆序数增得最快的字符插入
                index = i;
                max = temp;
            }
            suf[i]--;
        }
        suf[index]++;
    }

    public static int getRe(int c) {// 获取最大逆序数
        int i = 0, cnt = 0;
        while (pre[i] != 0) {
            if (pre[i] > (c + 'a')) {
                cnt++;
            }
            ++i;
        }
        for (i = 0; i < 26; ++i) {
            if (i != c) {
                cnt += suf[i];
            }
        }
        return cnt;
    }

    public static void getans(int num, int l) {
        for (int i = 0; i < l; ++i) {
            for (int j = 0; j < 26; ++j) {
                pre[i] = j + 'a';
                MaxStr(l);
                if (renum() >= num) {
                    break;
                }
            }
        }
    }
}

38.饮料换购

题目描述

乐羊羊饮料厂正在举办一次促销优惠活动。乐羊羊 C 型饮料,凭 3 个瓶盖可以再换一瓶 C 型饮料,并且可以一直循环下去(但不允许暂借或赊账)。

请你计算一下,如果小明不浪费瓶盖,尽量地参加活动,那么,对于他初始买入的 n 瓶饮料,最后他一共能喝到多少瓶饮料。

输入描述

输入一个整数 n(0n(0<n<1000),表示开始购买的饮料数量。

输出描述

输出一个整数,表示实际得到的饮料数

输入输出样例

示例

输入

100

输出

149

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 256M

代码

import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改

public class Main {
        public static void printResult(int n) {
        int sum = n;
        while(n > 2) {
            sum += n / 3;
            n = n / 3 + n % 3;
        }
        System.out.println(sum);
        return;
    }
    
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        printResult(n);
    }
}
形式一
import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改

public class Main {
        public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int get = n;
        while(n >= 3) {
            int t = n / 3;
            get += t;
            n -= 3 * t;
            n += t;
        }
        System.out.println(get);
    }
}
形式二

39.日期问题

题目描述

小明正在整理一批历史文献。这些历史文献中出现了很多日期。小明知道这些日期都在 1960 年 1 月 1 日至 2059 年 12 月 31 日。令小明头疼的是,这些日期采用的格式非常不统一,有采用年/月/日的,有采用月/日/年的,还有采用日/月/年的。

更加麻烦的是,年份也都省略了前两位,使得文献上的一个日期,存在很多可能的日期与其对应。

比如 02/03/04,可能是 2002 年 03 月 04 日、2004 年 02 月 03 日或 2004 年 03 月 02 日。

给出一个文献上的日期,你能帮助小明判断有哪些可能的日期对其对应吗?

输入描述

一个日期,格式是 "AA/BB/CCAA/BB/CC" (0 \leq A, B, C \leq 90A,B,C9)。

输出描述

输出若干个不相同的日期,每个日期一行,格式是 "yyyy-MM-ddyyyy?MM?dd"。多个日期按从早到晚排列。

输入输出样例

示例

输入

02/03/04

输出

2002-03-04
2004-02-03
2004-03-02

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 256M

代码

import java.util.*;
// 1:无需package
// 2: 类名必须Main, 不可修改

public class Main {
    static int[] m = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    static List list = new ArrayList<>();    // list
    static TreeSet set = new TreeSet<>();    // set 会去重,并自动排好序

    // 判断闰年
    static int judge(int year) {
        if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) return 1;
        return 0;
    }

    // 获取每个月的天数
    static int getDays(int year, int month) {
        if (month == 2) return 28 + judge(year);
        return m[month];
    }

    static void func(int year, int month, int day) {
        if (year <= 59)
            year = year + 2000;
        else
            year = year + 1900;
        if (month <= 12 && month >= 1 && getDays(year, month) >= day && day > 0) {
            if (month < 10 && day < 10)
                set.add(Integer.parseInt("" + year + "0" + month + "0" + day));
            else if (month < 10)
                set.add(Integer.parseInt("" + year + "0" + month + day));
            else if (day < 10)
                set.add(Integer.parseInt("" + year + month + "0" + day));
            else
                set.add(Integer.parseInt("" + year + month + day));
        }
    }


    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String str;
        str = scanner.next();
        int a, b, c;
        String[] s = str.split("/");
        a = Integer.parseInt(s[0]);
        b = Integer.parseInt(s[1]);
        c = Integer.parseInt(s[2]);
        // AA/BB/CC  CC/AA/BB  CC/BB/AA
        func(a, b, c);
        func(c, a, b);
        func(c, b, a);
        list.addAll(set);
        for (int i = 0; i < list.size(); i++) {
            String result = "" + list.get(i);
            System.out.println(result.substring(0, 4) + "-" + result.substring(4, 6) + "-" + result.substring(6, 8));
        }
    }
}
法一
import java.util.*;

public class Main {
    static int[] m = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    static List list = new ArrayList<>();    // list
    static TreeSet set = new TreeSet<>();    // set 会去重,并自动排好序

    // 判断闰年
    static int judge(int year) {
        if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) return 1;
        return 0;
    }

    // 获取每个月的天数
    static int getDays(int year, int month) {
        if (month == 2) return 28 + judge(year);
        return m[month];
    }

    static void func(int year, int month, int day) {
        if (year <= 59)
            year = year + 2000;
        else
            year = year + 1900;
        if (month <= 12 && month >= 1 && getDays(year, month) >= day && day > 0) {
            if (month < 10 && day < 10)
                set.add(Integer.parseInt("" + year + "0" + month + "0" + day));
            else if (month < 10)
                set.add(Integer.parseInt("" + year + "0" + month + day));
            else if (day < 10)
                set.add(Integer.parseInt("" + year + month + "0" + day));
            else
                set.add(Integer.parseInt("" + year + month + day));
        }
    }


    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String str;
        str = scanner.next();
        int a, b, c;
        String[] s = str.split("/");
        a = Integer.parseInt(s[0]);
        b = Integer.parseInt(s[1]);
        c = Integer.parseInt(s[2]);
        // AA/BB/CC  CC/AA/BB  CC/BB/AA
        func(a, b, c);
        func(c, a, b);
        func(c, b, a);
        list.addAll(set);
        for (int i = 0; i < list.size(); i++) {
            String result = "" + list.get(i);
            System.out.println(result.substring(0, 4) + "-" + result.substring(4, 6) + "-" + result.substring(6, 8));
        }
    }
}
法二

40.测试次数

题目描述

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

X 星球的居民脾气不太好,但好在他们生气的时候唯一的异常举动是:摔手机。

各大厂商也就纷纷推出各种耐摔型手机。x星球的质监局规定了手机必须经过耐摔测试,并且评定出一个耐摔指数来,之后才允许上市流通。

X 星球有很多高耸入云的高塔,刚好可以用来做耐摔测试。塔的每一层高度都是一样的,与地球上稍有不同的是,他们的第一层不是地面,而是相当于我们的 22 楼。

如果手机从第 77 层扔下去没摔坏,但第 88 层摔坏了,则手机耐摔指 =7=7。 特别地,如果手机从第 11 层扔下去就坏了,则耐摔指数 =0=0。 如果到了塔的最高层第 nn 层扔没摔坏,则耐摔指数 =n=n。

为了减少测试次数,从每个厂家抽样 33 部手机参加测试。

某次测试的塔高为 10001000 层,如果我们总是采用最佳策略,在最坏的运气下最多需要测试多少次才能确定手机的耐摔指数呢?

请填写这个最多测试次数。

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 128M

代码

import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改

//3部手机,1000层楼,最坏需要测试几次
//该算法可用递归+二分进行优化,这里作为填空题直接暴力递归即可

public class Main {
        
    //备忘录,防止重复循环,给一个维度较大的值即可
    private static int[][] memo=new int[3000][3000];
    
    public static void main(String[] args) {
    
        System.out.println(dp(3, 1000));
        
    }
    
    //m个手机,第n层楼开始丢
    private static int dp(int m,int n) {
        
        //定义一个较大的值
        int ans = 1000;
        
        //只有一个手机时,需要测n次
        if(m==1) return n;
        
        //楼层为0时,不用测试
        if(n==0) return 0;
        
        //记录过,直接返回
        if((memo[m][n]>=1)) return memo[m][n];
        
        //遍历楼层数
        for(int i=1;i<=n;i++) {
            
            //分手机碎和没碎两种情况写状态转移方程
            //min表示“至少”,max表示“最坏”
            ans = Math.min(Math.max(dp(m, n-i), dp(m-1, i-1))+1,ans);
            
            //表示记录过
            memo[m][n] = ans;
        }
        
        return ans;
    } 
}
法一
/**
dp[n][c] : n表示还要测试的楼层,c表示手机数量
dp数组的定义:n层楼,c部手机需要测试的次数
*/

public class Main {
    public static void main(String[] args) {
        System.out.println(f(1000,3));
    }
    public static int f(int n, int c) {
        if(c==1) {
            return n;//一个手机只能一层一层测
        }
        int[][] dp=new int[n+1][c+1];

    //初始化dp
        for(int i=1;i) {
            dp[i][1]=i;//当只有一部手机时,其测试次数为楼层数,因为只能一层一层测试
        }

        for(int i=1;i//遍历楼层
            for(int j=2;j//遍历手机

                int min=Integer.MAX_VALUE;//表示int数据类型的最大取值数:2 147 483 647

                for(int k=1;k) {
                    min=Math.min(min,Math.max(dp[k-1][j-1], dp[i-k][j]));
          //dp两种情况:1.手机碎了,则手机数量建议,测试剩下的楼层(碎的是还有k层,则测试剩下的k-1层)
          // 2.手机没碎,手机数不变,测试剩下的楼层(总楼层数-已经测试好的楼层数)
                }
                dp[i][j]=min+1;
            }
        }
        return dp[n][c];
    }
}
法二

41.第几天

题目描述

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

20002000 年的 11 月 11 日,是那一年的第 11 天。

那么,20002000 年的 55 月 44 日,是那一年的第几天?

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 128M

代码

import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改

public class Main {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        System.out.println(31+29+31+30+4);
        scan.close();
    }
}

42.答疑

题目描述

有 nn 位同学同时找老师答疑。每位同学都预先估计了自己答疑的时间。

老师可以安排答疑的顺序,同学们要依次进入老师办公室答疑。 一位同学答疑的过程如下:

  1. 首先进入办公室,编号为 ii 的同学需要 s_isi? 毫秒的时间。
  2. 然后同学问问题老师解答,编号为 ii 的同学需要 a_iai? 毫秒的时间。
  3. 答疑完成后,同学很高兴,会在课程群里面发一条消息,需要的时间可 以忽略。
  4. 最后同学收拾东西离开办公室,需要 e_iei? 毫秒的时间。一般需要 1010 秒、2020 秒或 3030 秒,即 e_iei? 取值为 1000010000,2000020000 或 3000030000。

一位同学离开办公室后,紧接着下一位同学就可以进入办公室了。

答疑从 00 时刻开始。老师想合理的安排答疑的顺序,使得同学们在课程群 里面发消息的时刻之和最小。

输入描述

输入第一行包含一个整数 nn,表示同学的数量。

接下来 nn 行,描述每位同学的时间。其中第 ii 行包含三个整数 s_isi?a_iai?e_iei?,意义如上所述。

其中有 ,1 ≤ n ≤ 1000,1 ≤ s_i ≤ 60000,1 ≤ a_i ≤ 10^6, e_i ∈ {10000, 20000, 30000}1n10001si?600001ai?106ei?10000,20000,30000,即 e_iei? 一定是 10000、20000、30000100002000030000 之一。

输出描述

输出一个整数,表示同学们在课程群里面发消息的时刻之和最小是多少。

输入输出样例

示例

输入

3
10000 10000 10000
20000 50000 20000
30000 20000 30000

输出

280000

运行限制

  • 最大运行时间:3s
  • 最大运行内存: 128M

代码

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改

public class Main {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        //在此输入您的代码...
        int n = scan.nextInt();
        ArrayList l = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            l.add(new Student(scan.nextInt(), scan.nextInt(), scan.nextInt()));
        }
        //对s、a、e三个时间加起来进行排序
        Collections.sort(l, new Comparator() {
            @Override
            public int compare(Student o1, Student o2) {
                if (o1.sum+o1.e > o2.sum+o2.e)
                    return 1;
                else if (o1.sum+o1.e < o2.sum+o2.e)
                    return -1;
                else
                    return 0;
            }
        });
        long ans = 0;
        long t = 0;//上一名用的时间
        for (int i = 0; i < n; i++) {
            ans += t += l.get(i).sum;
            t +=l.get(i).e;
        }
        System.out.println(ans);
        scan.close();
    }

    static class Student {
        int s;
        int a;
        int e;
        int sum;//=s+a :到发消息时候用的时间

        public Student(int s, int a, int e) {
            this.s = s;
            this.a = a;
            this.e = e;
            this.sum = this.s + this.a;
        }

    }
}

43.取位数

题目描述

本题为代码补全填空题,请将题目中给出的源代码补全,并复制到右侧代码框中,选择对应的编译语言(C/Java)后进行提交。若题目中给出的源代码语言不唯一,则只需选择其一进行补全提交即可。复制后需将源代码中填空部分的下划线删掉,填上你的答案。提交后若未能通过,除考虑填空部分出错外,还需注意是否因在复制后有改动非填空部分产生错误。

求1个整数的第k位数字有很多种方法。 以下的方法就是一种。

请仔细分析源码,填写划线部分缺少的内容。

代码

import java.util.*;
public class Main
{
    static int len(int x){
        if(x<10) return 1;
        return len(x/10)+1;
    }
    
    // 取x的第k位数字
    static int f(int x, int k){
        if(len(x)-k==0) return x%10;
        return (int) ((x / (Math.pow(10, (len(x) - k)))) % 10);  //填空
    }
    
    public static void main(String[] args)
    {
        int x = 23513;
        //System.out.println(len(x));
        System.out.println(f(x,3));
        System.out.println(f(893275,2));
    }
}
(int) ((x / (Math.pow(10, (len(x) - k)))) % 10)
import java.util.*;
public class Main
{
    static int len(int x){
        if(x<10) return 1;
        return len(x/10)+1;
    }
    
    // 取x的第k位数字
    static int f(int x, int k){
        if(len(x)-k==0) return x%10;
        return f(x/10,k);  //填空
    }
    
    public static void main(String[] args)
    {
        int x = 23513;
        //System.out.println(len(x));
        System.out.println(f(x,3));
        System.out.println(f(893275,2));
    }
}
f(x/10,k)

44.完全二叉树的权值

题目描述

给定一棵包含 NN 个节点的完全二叉树,树上每个节点都有一个权值,按从 上到下、从左到右的顺序依次是 A_1, A_2, ··· A_NA1?,A2?,???AN?,如下图所示:

现在小明要把相同深度的节点的权值加在一起,他想知道哪个深度的节点 权值之和最大?如果有多个深度的权值和同为最大,请你输出其中最小的深度。

注:根的深度是 1。

输入描述

第一行包含一个整数 N(1 \leq N \leq 10^5)N1N105)。

第二行包含 NN 个整数 A_1, A_2, ··· A_N (?10^5 \leq A_i \leq 10^5)A1?,A2?,???AN??105Ai?105)。

输出描述

输出一个整数代表答案。

输入输出样例

示例

输入

7
1 6 5 4 3 2 1

输出

2

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 256M

代码

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    static int N = 100010;
    static int n;
    static int[] a = new int[N];
    
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        n = Integer.parseInt(br.readLine());
        String[] s = br.readLine().split(" ");
        for(int i = 1;i <= n;i++) a[i] = Integer.parseInt(s[i - 1]); 
        long max = Integer.MIN_VALUE;
        int depth = 0;
        for(int d = 1, i = 1;i <= n;d++, i *= 2) {
            long sum = 0;//当前层的权值和
            for(int j = i;j < i + (1 << d - 1) && j <= n;j++) {//遍历该层
                sum += a[j];
            }
            if(sum > max) {
                max = sum;
                depth = d;
            }
        }
        System.out.println(depth);
    }
}
法一
import java.util.*;

public class Main {
    public static void main(final String[] args) {
        Scanner sc = new Scanner(System.in);
        int n=sc.nextInt();
        int[]nums=new int[n+1];
        long maxSum=0;
        int minDeep=Integer.MAX_VALUE;
        for(int i=1;i<=n;i++)nums[i]=sc.nextInt();
        int deep=0;
        for(int i=1;i<=n;i=i+(int)Math.pow(2, deep-1)) {
            long sum=0;
            //最后一层可能不满,一定要加上j<=n,否则数组越界
            for(int j=i;jint)Math.pow(2, deep)&&j<=n;j++) {
                sum+=nums[j];
            }
            if(sum>maxSum) {
                minDeep=deep+1;
                maxSum=sum;
            }
            deep++;
        }
        System.out.println(minDeep);
    }
}
法二

45.迷宫

题目描述

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

X 星球的一处迷宫游乐场建在某个小山坡上。它是由 10 \times 1010×10 相互连通的小房间组成的。

房间的地板上写着一个很大的字母。我们假设玩家是面朝上坡的方向站立,则:

  • LL 表示走到左边的房间,
  • RR 表示走到右边的房间,
  • UU 表示走到上坡方向的房间,
  • DD 表示走到下坡方向的房间。

X 星球的居民有点懒,不愿意费力思考。他们更喜欢玩运气类的游戏。这个游戏也是如此!

开始的时候,直升机把 100100 名玩家放入一个个小房间内。玩家一定要按照地上的字母移动。

迷宫地图如下:

UDDLUULRUL
UURLLLRRRU
RRUURLDLRD
RUDDDDUUUU
URUDLLRRUU
DURLRLDLRL
ULLURLLRDU
RDLULLRDDD
UUDDUDUDLL
ULRDLUURRR

请你计算一下,最后,有多少玩家会走出迷宫,而不是在里边兜圈子?

如果你还没明白游戏规则,可以参看下面一个简化的 4x4 迷宫的解说图:

运行限制

    • 最大运行时间:1s
    • 最大运行内存: 128M

代码

import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改

public class Main {
    public static void main(String[] args) {
        int ans=0;
        for(int i=0;i<10;i++)
            for(int j=0;j<10;j++)
                if(ok(i,j))
                    ans++;
        System.out.println(ans);
    }

    static char[][] ch = new char[][] {
            "UDDLUULRUL".toCharArray(),
            "UURLLLRRRU".toCharArray(),
            "RRUURLDLRD".toCharArray(),
            "RUDDDDUUUU".toCharArray(),
            "URUDLLRRUU".toCharArray(),
            "DURLRLDLRL".toCharArray(),
            "ULLURLLRDU".toCharArray(),
            "RDLULLRDDD".toCharArray(),
            "UUDDUDUDLL".toCharArray(),
            "ULRDLUURRR".toCharArray()};

    static boolean ok(int x,int y) {
        int t=100;//这里的数字可以任意(但是不能过小)表示允许走多少步
        while(t-->0) {
            if(x<0 || x>=10 || y<0 || y>=10)
                return true;
            if(ch[x][y]=='U')
                x--;
            else if(ch[x][y]=='D')
                x++;
            else if(ch[x][y]=='L')
                y--;
            else if(ch[x][y]=='R')
                y++;
        }
        return false;
    }
}

46.相乘

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。 小蓝发现,他将 11 至 10000000071000000007 之间的不同的数与 20212021 相乘后再求除以 10000000071000000007 的余数,会得到不同的数。 小蓝想知道,能不能在 11 至 10000000071000000007 之间找到一个数,与 20212021 相乘后 再除以 10000000071000000007 后的余数为 999999999999999999。如果存在,请在答案中提交这个数; 如果不存在,请在答案中提交 00。

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 128M

代码

import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改

public class Main {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        //在此输入您的代码...
        for(long i=0; i<1000000008; i++){
          if(i*2021%1000000007 == 999999999){
            System.out.println(i);
            break;
          }
        }
        scan.close();
    }
}

47.全球变暖

题目描述

你有一张某海域 NxNNxN 像素的照片,"."表示海洋、"#"表示陆地,如下所示:

.......

.##....

.##....

....##.

..####.

...###.

.......

其中"上下左右"四个方向上连在一起的一片陆地组成一座岛屿。例如上图就有 2 座岛屿。

由于全球变暖导致了海面上升,科学家预测未来几十年,岛屿边缘一个像素的范围会被海水淹没。具体来说如果一块陆地像素与海洋相邻(上下左右四个相邻像素中有海洋),它就会被淹没。

例如上图中的海域未来会变成如下样子:

.......

.......

.......

.......

....#..

.......

.......

请你计算:依照科学家的预测,照片中有多少岛屿会被完全淹没。

输入描述

第一行包含一个整数 N\ (1 \leq N \leq 1000)N (1N1000)。

以下 NN 行 NN 列代表一张海域照片。

照片保证第 1 行、第 1 列、第 NN 行、第 NN 列的像素都是海洋。、

输出一个整数表示答案。

输入输出样例

示例

输入

7
.......
.##....
.##....
....##.
..####.
...###.
.......

输出

1

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 256M

代码

import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改

public class Main {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int n = scan.nextInt();
        char[][] map = new char[n][n];
        boolean[][] vis = new boolean[n][n];
        for (int i = 0; i < n; i++) {
            map[i] = scan.next().toCharArray();
        }
        int fieldCount = 0;
        int resCount = 0;
        boolean [] flag = {false,false,false,false};
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if(vis[i][j] == false && map[i][j] == '#'){
                    fieldCount+=1;
                    dfs(map,i,j,vis,flag);
                    if(flag[0] && flag[1] && flag[2] && flag[3]){
                        resCount+=1;
                        flag[0] = false;
                        flag[1] = false;
                        flag[2] = false;
                        flag[3] = false;
                    }
                }
            }
        }
        System.out.println(fieldCount-resCount);
    }
 
    private static void check(char[][] map, int i, int j,boolean [] flag) {
        if(map[i][j] == '.' || i<0 || i == map.length || j<0 || j == map[0].length){
            return;
        }
        if(i+1 < map.length && map[i+1][j] == '#'){
            flag[0] = true;
        }
        if(j+1< map[0].length && map[i][j+1] == '#'){
            flag[1] = true;
        }
        if(i-1>=0 && map[i-1][j] == '#'){
            flag[2] = true;
        }
        if(j-1>=0 && map[i][j-1] == '#'){
            flag[3] = true;
        }
    }
 
    private static void dfs(char[][] map, int i, int j, boolean [][] vis,boolean[] flag) {
        if(map[i][j] == '.' || i<0 || i == map.length || j<0 || j == map[0].length){
            return;
        }
        if(!flag[0] || !flag[1] || !flag[2] || !flag[3]){
            flag[0] = false;
            flag[1] = false;
            flag[2] = false;
            flag[3] = false;
        }
        vis[i][j] = true;
        check(map,i,j,flag);
        if(map[i+1][j] == '#' && vis[i+1][j] == false){
            dfs(map,i+1,j,vis,flag);
        }
        if(map[i][j+1] == '#' && vis[i][j+1] == false){
            dfs(map,i,j+1,vis,flag);
        }
        if(map[i-1][j] == '#' && vis[i-1][j] == false){
            dfs(map,i-1,j,vis,flag);
        }
        if(map[i][j-1] == '#' && vis[i][j-1] == false){
            dfs(map,i,j-1,vis, flag);
        }
    }
}
法一
package test;

import java.util.Scanner;

public class 相乘 {
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();//输入n构成n*n二维数组
        String[] s = new String[n];
        char[] c;
        char[][] a = new char[n][n];//存储输入的字符
        char[][] b = new char[n][n];//存储输出的字符

        //输入
        for (int i = 0;i < n;i++){
            s[i] = sc.next();
            c = s[i].toCharArray();
            for (int j = 0; j < n;j++){
                a[i][j] = c[j];
                b[i][j] = c[j];
            }
        }

        char temp;
        //题目的要求是第一行、第一列、最后一行、最后一列都是.
        for (int i = 0;i < n;i++){
            for (int j = 0; j < n;j++){
                if (i != 0 && i != 6 && j != 0 && j != 6){
                    temp = a[i][j];
                    if (temp == '#'){
                        if ((temp != a[i][j-1]) || (temp != a[i-1][j]) || (temp != a[i][j+1]) || (temp != a[i+1][j])){
                            b[i][j] = '.';
                        }
                    }
                }else {
                    b[i][j] = '.';
                }
            }

        }

        //输出
        for (int i = 0;i < n;i++){
            for (int j = 0; j < n;j++){
                System.out.print(b[i][j]);
            }
            System.out.println();
        }
    }
}
法二(输出图形)

48.平行切分

题目描述

平面上有 NN 条直线,其中第 ii 条直线是 y = A_i \times x + B_iy=Ai?×x+Bi?

请计算这些直线将平面分成了几个部分。

输入描述

第一行包含一个整数 NN。

以下 NN 行,每行包含两个整数 A_i, B_iAi?,Bi?

其中,1 \leq N \leq 1000, ?10^5 \leq A_i,B_i \leq 10^51N1000,?105Ai?,Bi?105。

输出描述

一个整数代表答案。

输入输出样例

示例

输入

3
1 1
2 2
3 3

输出

6

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 256M

代码

import java.util.Scanner;

public class Main {
    
    public static void main(String args[]) {
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt();
        int[] a=new int[n];
        int[] b=new int[n];
        double[] c=new double[n-1];
        int count=1;
        for(int i=0;i) {
            a[i]=sc.nextInt();
            b[i]=sc.nextInt();
            if(i==0) {count++;continue;}
            int flag=0;
            for(int e=0;eif(a[e]==a[i]&&b[e]==b[i]) flag=1;}
            if(flag==1) {i--;n--;continue;}
            int f=0;
            for(int j=0;j) {
                if(a[i]==a[j]) {f++;continue;}
            c[j-f]=(double)(b[i]-b[j])/(double)(a[j]-a[i]);
            flag=0;
            for(int k=0;kif(c[k]==c[j-f])flag=1;}
            if(flag==0)count++;
            }
            count++;
        }
        sc.close();
        System.out.println(count);
    }
}

49.平方和

题目描述

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

小明对数位中含有 2、0、1、92019 的数字很感兴趣,在 11 到 4040 中这样的数包括 1、2、9、1012910 至 32、393239 和 4040,共 2828 个,他们的和是 574574,平方和是 1436214362。

注意,平方和是指将每个数分别平方后求和。

请问,在 11 到 20192019 中,所有这样的数的平方和是多少?

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 128M

代码

import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改

public class Main {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Long result = 0l;
        for (int i = 1; i <= 2019; i++) {
            String s = new String("" + i + "");
            if (s.contains("0") || s.contains("1") || s.contains("2") || s.contains("9")) {
                result += (long)Math.pow(i, 2);
            }
        }
        System.out.println(result);
    }
}
法一
import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改

public class Main {
     public static void main(String[] args) {
         long sum=0,pf=0,pfh=0;int count=0;boolean bool=true;
         for(int i=1;i<=2019;i++) {
             int j = i;
             while(j!=0) {
                 sum=j%10;
                 j = j/10;
                 if(sum==2||sum==0||sum==1||sum==9) {
                     pf=i*i;
                     pfh=pfh+pf;
                     count++;
                     j=0;
                 }
             }
         }
         System.out.println(pfh);
      }
    }
法二
import java.math.BigInteger;

public class Main {
/*题目描述
本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。
小明对数位中含有2、0、1、9的数字很感兴趣,在1到40中这样的数包括1、2、9、10至32、39和40, 共28个,他们的和是574,
平方和是14362.
注意,平方和是指将每个数分别平方后求和。
请问,在1到2019中,所有这样的数的平方和是多少?

*/    public static void main(String[] args) {
        // TODO Auto-generated method stub
            BigInteger b=new BigInteger("0");
        for (int i = 1; i <= 2019; i++) {
            String s=String.valueOf(i);
            int ls=s.length();
            
            s=s.replace("2", "");
            s=s.replace("0", "");
            s=s.replace("1", "");
            s=s.replace("9", "");
            
            if(ls!=s.length()){
                b=b.add(new BigInteger(String.valueOf(i*i)));
                
            }else{
                continue;
            }
        }
        System.out.println(b.toString());
    }

}
法三

50.受伤的皇后

题目描述

有一个 n \times nn×n 的国际象棋棋盘(nn 行 nn 列的方格图),请在棋盘中摆放 nn 个受伤的国际象棋皇后,要求:

  1. 任何两个皇后不在同一行。
  2. 任何两个皇后不在同一列。
  3. 如果两个皇后在同一条 45 度角的斜线上,这两个皇后之间行号的差值至少为 3 。

请问一共有多少种摆放方案。

输入描述

输入的第一行包含一个整数 nn。

其中,1 \leq n \leq 101n10。

输出描述

输出一个整数,表示答案。

输入输出样例

示例 1

输入

4

输出

2

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 128M

代码

import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改

public class Main {
    static int a[]=new int[100];  //存储皇后放置的位置
    static int sum=0;
    static int n;
    static boolean check(int r,int c) {
        for (int i = 0; i ) {
            if(a[i]==c)
                return false;
            if(Math.abs(r-i)==Math.abs(c-a[i]) && r-i<3)
                return false;
        }             //满足条件,不在同行同列同3步对角线内            
        return true;
    }
    static void dfs(int r) {  //r行
        if(r==n)              //结束状态
            sum++;
        for (int c = 0; c < n; c++) {  //r行 c列
            if(check(r,c)) {              //满足条件,不在同行同列同3步对角线内
                a[r]=c;                //放置皇后
                dfs(r+1);
            }
        }
        
    }
    
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner sc = new Scanner(System.in);
        n=sc.nextInt();  //n个皇后        
        dfs(0);
        System.out.print(sum);
        
    }
}