第十四届蓝桥杯三月真题刷题训练——第 24 天

目录

第 1 题:旋转

题目描述

输入描述

输出描述

输入输出样例

运行限制

代码:

思路:

第 2 题:附近最小_单调队列模板

代码:

第 3 题:扫地机器人_二分

题目描述

输入描述

输出描述

输入输出样例

运行限制

代码:

思路:


第 1 题:旋转

题目描述

图片旋转是对图片最简单的处理方式之一,在本题中,你需要对图片顺时针旋转 90 度。

我们用一个 n×m 的二维数组来表示一个图片,例如下面给出一个 3×4 的 图片的例子:

1 3 5 7

9 8 7 6

3 5 9 7

这个图片顺时针旋转 90 度后的图片如下:

3 9 1

5 8 3

9 7 5

7 6 7

给定初始图片,请计算旋转后的图片。

输入描述

输入的第一行包含两个整数 n,m 分别表示行数和列数。

接下来 n 行,每行 m 个整数,表示给定的图片。图片中的每个元素(像 素)为一个值为 0 至 255 之间的整数(包含 0 和 255)。

输出描述

输出 m 行 n 列,表示旋转后的图片。

输入输出样例

示例

输入

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

输出

3 9 1
5 8 3
9 7 5
7 6 7

运行限制

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

代码:

package 第十四届蓝桥杯三月真题刷题训练.day24;

import java.io.*;

/**
 * @author yx
 * @date 2023-03-27 8:30
 */
public class 旋转 {
    static PrintWriter out =new PrintWriter(System.out);
    static BufferedReader ins=new BufferedReader(new InputStreamReader(System.in));
    static StreamTokenizer in=new StreamTokenizer(ins);
    /**
     * 输入
     * in.nextToken()
     * int a= (int)in.nval;
     *
     * 输出
     * out.print();
     * out.flush();
     *
     * 读文件:
     * BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("C:\\Users\\yx\\Desktop\\primes.txt")));
     * String s = br.readLine();s读取每一行数据
     * if (s == null)break;读取文件终止的语句
     **/
    public static void main(String[] args) throws IOException {
        in.nextToken();
        int n=(int) in.nval;
        in.nextToken();
        int m=(int) in.nval;
        int[][] nums=new int[n][m];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                in.nextToken();
                nums[i][j]=(int) in.nval;
            }
        }
        for (int i = 0; i < m; i++) {
            for (int j = n-1; j >= 0; j--) {
                out.print(nums[j][i]+" ");
            }
            out.println();
        }
        out.flush();
    }
}

思路:

按行存储,按列输出

第 2 题:附近最小_单调队列模板

代码:

第 3 题:扫地机器人_二分

题目描述

小明公司的办公区有一条长长的走廊,由 N 个方格区域组成,如下图所示。

走廊内部署了 K 台扫地机器人,其中第 i 台在第 Ai 个方格区域中。已知扫地机器人每分钟可以移动到左右相邻的方格中,并将该区域清扫干净。

请你编写一个程序,计算每台机器人的清扫路线,使得

  1. 它们最终都返回出发方格,

  2. 每个方格区域都至少被清扫一遍,

  3. 从机器人开始行动到最后一台机器人归位花费的时间最少。

注意多台机器人可以同时清扫同一方块区域,它们不会互相影响。

输出最少花费的时间。 在上图所示的例子中,最少花费时间是 6。第一台路线:2-1-2-3-4-3-2,清 扫了 1、2、3、4 号区域。第二台路线 5-6-7-6-5,清扫了 5、6、7。第三台路线 10-9-8-9-10,清扫了 8、9 和 10。

输入描述

第一行包含两个整数 N,K。

接下来 K 行,每行一个整数 Ai​。

其中,1≤K<N≤10^5,1≤Ai≤N。

输出描述

输出一个整数表示答案。

输入输出样例

示例

输入

10 3
5
2
10

输出

6

运行限制

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

代码:

package 第十四届蓝桥杯三月真题刷题训练.day24;

import java.io.*;
import java.util.Arrays;

/**
 * @author yx
 * @date 2023-03-27 10:00
 */
public class 扫地机器人_二分 {
    //参考博客:https://blog.csdn.net/weixin_43336281/article/details/122506874
    static PrintWriter out = new PrintWriter(System.out);
    static BufferedReader ins = new BufferedReader(new InputStreamReader(System.in));
    static StreamTokenizer in = new StreamTokenizer(ins);
    static int N;
    static int K;
    static int[]robots;
    /**
     * 输入
     * in.nextToken()
     * int a= (int)in.nval;
     * <p>
     * 输出
     * out.print();
     * out.flush();
     * <p>
     * 读文件:
     * BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("C:\\Users\\yx\\Desktop\\primes.txt")));
     * String s = br.readLine();s读取每一行数据
     * if (s == null)break;读取文件终止的语句
     **/
    public static void main(String[] args) throws IOException {
        String[] sp = ins.readLine().split(" ");
        N = Integer.parseInt(sp[0]);
        K = Integer.parseInt(sp[1]);
        robots = new int[K];
        for (int i = 0; i < K; i++) {
            in.nextToken();
            robots[i] = (int) in.nval;
        }
        //好恶心,需要自己排序
        Arrays.sort(robots);
        int l = 0;
        int r = N;
        int ans=0;
        while (l <= r) {
            //二分枚举最少花费时间
            int mid = (l + r) / 2;
            //check为true表示步数偏大,可以减小步数优化,为false表示步数偏小,要增加步数
            if (!check(mid)) {
                ans = mid;
                l = mid + 1;
            } else {
                r = mid - 1;
            }
        }
        System.out.print(2*ans);
    }
    static boolean check(int n){
        //定义一个右边界
        int r=0;
        for (int i = 0; i < K; i++) {
            if(robots[i]-n<=r){
                //此时存在两种情况
                /*
                1、当第i个机器人在第i-1个机器人右边界的右边:
                说明这第i个机器人要扫左边,更新右边界r=r+n
                2、当第i个机器人在第i-1个机器人的左边:
                说明这第i个机器人不用扫左边,只需要扫右边和自己
                更新右边界r=robots[i]+n-1
                (减1是因为机器人自己的位置也要扫)
                 */
                r=Math.min(robots[i]-1,r)+n;
            }else {
                return false;
            }
        }
        return r>=N;
    }
}

思路:

猜你喜欢

转载自blog.csdn.net/m0_55858611/article/details/129788074
今日推荐