第十三届蓝桥杯国赛JavaB组题解

2023-10-27 19:50

本文主要是介绍第十三届蓝桥杯国赛JavaB组题解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

A. 重合次数

在这里插入图片描述
思路:

枚举不同的时刻,判断哪些时刻秒针和分针表示的数字是相同的。这道题坑就坑在:xx:59:59 xx:00:00分针和时。也就是说一个小时会重叠两次。
题目要求是分钟和秒钟的重叠次数,故时钟,分钟,秒钟同时重叠的次数不算(这题还是有点咬文嚼字了,我说怎么比答案多了8次)。

代码:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;public class Main {static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));static StreamTokenizer in = new StreamTokenizer(br);public static int nextInt() throws IOException {in.nextToken();return (int) in.nval;}public static void main(String[] args) {// TODO Auto-generated method stubint h = 6, m = 13, s = 22;int cnt = 0;while (h != 14 || m != 36 || s != 20) {if (m == s) cnt++;s++;if (s == 60) {m++;s = 0;}if (m == 60) {h++;m = 0;}}// 减去整点重复System.out.println(cnt - 8);}
}

B. 数数

在这里插入图片描述
思路:

这道题本来想通过搜索判断一个数是否可以用12个质因数表示,但是失败了。后来想到可以用试除法分解质因数判断一个数是否可以被分解成12个质因子,虽然最后也跑了一会儿不过作为填空题还是给过了。

代码:

public class Main {static int ans;public static boolean check(int x) {int cnt = 0;for (int i = 2; i <= x / i; i++) {if (x % i == 0) {while (x % i == 0) {x /= i;cnt++;}}}return cnt == 12;}public static void main(String[] args) {// TODO Auto-generated method stub// for (int i = 2333333; i <= 23333333; i++) //     if (check(i)) ans++;System.out.println(25606);}
}

C. 左移右移

在这里插入图片描述
在这里插入图片描述
思路:

初始的想法是保存每个数的位置,当某个数左移的时候,左边的每个数的位置都+1,右边的数不变;当某个数右移的时候,右边的每个数的位置都-1,左边的数不变,自然而然想到了差分,算出位置后,接着再根据位置输出即可。但是后来想想每次都要求得每个数的位置,复杂度为 O ( N ) O(N) O(N),一共有 M M M 个操作,复杂度就是 O ( N M ) O(NM) O(NM),最大程度会 4 × 1 0 10 4 × 10^{10} 4×1010 ,显然会超时,这种做法不可取。

后来想到了用双链表进行求解,每次交换位置的时候要先删除再插入,在插入的时候更新元素的位置。在 O ( N ) O(N) O(N) 的复杂度内可以得到正确答案。

代码:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;public class Main {static final int N = 400010;static int[] e = new int[N], l = new int[N], r = new int[N], loc = new int[N];static int n, m, idx;static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));public static void insert(int k, int x) {loc[x] = idx;e[idx] = x;l[idx] = k;r[idx] = r[k];l[r[k]] = idx;r[k] = idx++;}public static void remove(int k) {r[l[k]] = r[k];l[r[k]] = l[k];}public static void main(String[] args) throws IOException {// TODO Auto-generated method stubString[] nm = br.readLine().split(" ");n = Integer.parseInt(nm[0]);m = Integer.parseInt(nm[1]);// 0为头节点,1为尾节点l[1] = 0;r[0] = 1;idx = 2;for (int i = 1; i <= n; i++) insert(l[1], i);while (m-- != 0) {String[] ops = br.readLine().split(" ");char op = ops[0].charAt(0);int x = Integer.parseInt(ops[1]);if (op == 'L') {remove(loc[x]);insert(0, x);} else {remove(loc[x]);insert(l[1], x);}}for (int i = r[0]; i != 1; i = r[i]) out.printf("%d ", e[i]);out.flush();}
}

D. 窗口

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
思路:

定义窗口类,存储相关信息:

static class Window implements Comparable<Window> {int pid, top, left, height, width, priority;Window(int pid, int top, int left, int height, int width, int priority) {this.pid = pid;this.top = top;this.left = left;this.height = height;this.width = width;this.priority = priority;}void move(int ver, int hor) {this.top += ver;this.left += hor;this.priority = ++pri;}void resize(int h, int w) {this.height = h;this.width = w;this.priority = ++pri;}@Overridepublic int compareTo(Window o) {// TODO Auto-generated method stubreturn priority - o.priority;}}

依次处理每个操作,更新窗口信息。接着将窗口按优先级从小到大排序,优先级为0的窗口不予处理。在根据排好序的窗口绘制图形,就能实现优先级较大的窗口处于顶层。

代码:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.HashSet;public class Main {static final int N = 300, M = 100010;static char[][] g = new char[N][N];static Window[] arr = new Window[M];static Window[] wins = new Window[M];static int n, m, k, pri = 0;static class Window implements Comparable<Window> {int pid, top, left, height, width, priority;Window(int pid, int top, int left, int height, int width, int priority) {this.pid = pid;this.top = top;this.left = left;this.height = height;this.width = width;this.priority = priority;}void move(int ver, int hor) {this.top += ver;this.left += hor;this.priority = ++pri;}void resize(int h, int w) {this.height = h;this.width = w;this.priority = ++pri;}@Overridepublic int compareTo(Window o) {// TODO Auto-generated method stubreturn priority - o.priority;}}static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));public static void draw(int x1, int y1, int x2, int y2) {for (int i = x1; i <= x2; i++) for (int j = y1; j <= y2; j++) {if (i < 0 || i >= n || j < 0 || j >= m) continue;if (i == x1 || i == x2) {if (j == y1 || j == y2) g[i][j] = '+';else g[i][j] = '-';} else if (j == y1 || j == y2) g[i][j] = '|';else g[i][j] = ' ';}}public static void main(String[] args) throws IOException {// TODO Auto-generated method stubString[] nm = br.readLine().split(" ");n = Integer.parseInt(nm[0]);m = Integer.parseInt(nm[1]);k = Integer.parseInt(br.readLine());HashSet<Integer> pSet = new HashSet<Integer>();for (int i = 0; i < k; i++) {String[] op = br.readLine().split(" ");int id = Integer.parseInt(op[1]);pSet.add(id);if (op[0].equals("new")) {int t = Integer.parseInt(op[2]);int l = Integer.parseInt(op[3]);int h = Integer.parseInt(op[4]);int w = Integer.parseInt(op[5]);arr[id] = new Window(id, t, l, h, w, ++pri);} else if (op[0].equals("move")) {int ver = Integer.parseInt(op[2]);int hor = Integer.parseInt(op[3]);arr[id].move(ver, hor);} else if (op[0].equals("resize")) {int h = Integer.parseInt(op[2]);int w = Integer.parseInt(op[3]);arr[id].resize(h, w);} else if (op[0].equals("close")) {arr[id].priority = 0;} else {arr[id].priority = ++pri;}}int num = 0;for (Integer id : pSet) {wins[num++] = arr[id];}Arrays.sort(wins, 0, num);for (int i = 0; i < n; i++)for (int j = 0; j < m; j++)g[i][j] = '.';for (int i = 0; i < num; i++) {if (wins[i].priority != 0) {int x1 = wins[i].top;int y1 = wins[i].left;int x2 = x1 + wins[i].height - 1;int y2 = y1 + wins[i].width - 1;draw(x1, y1, x2, y2);}}for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++)out.print(g[i][j]);out.println();}out.flush();  }
}

E. 迷宫

在这里插入图片描述
在这里插入图片描述
思路:
bfs求最短路,从终点一次bfs可以求得到所有点的最短距离,将所有点的最短距离相加再除以点数即可得到最短距离的数学期望。

代码:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;public class Main {static final int N = 2010, M = N * N, inf = 0x3f3f3f3f;static int[] h = new int[M], e = new int[N * 2], ne = new int[N * 2];static int[][] d = new int[N][N];static int[] dx = {-1, 0, 1, 0}, dy = {0, 1, 0, -1};static int n, m, idx;static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));static StreamTokenizer in = new StreamTokenizer(br);public static int nextInt() throws IOException {in.nextToken();return (int) in.nval;}public static void add(int a, int b) {e[idx] = b;ne[idx] = h[a];h[a] = idx++;}public static int get(int x, int y) {return x * N + y;}public static void bfs() {for (int i = 0; i <= n; i++)for (int j = 0; j <= n; j++)d[i][j] = inf;Queue<Integer> q = new LinkedList<Integer>();q.offer(n * N + n);d[n][n] = 0;while (!q.isEmpty()) {int v = q.poll();int x = v / N, y = v % N;for (int i = 0; i < 4; i++) {int tx = x + dx[i], ty = y + dy[i];if (tx <= 0 || tx > n || ty <= 0 || ty > n) continue;if (d[tx][ty] > d[x][y] + 1) {d[tx][ty] = d[x][y] + 1;q.offer(tx * N + ty);}}for (int i = h[v]; i != -1; i = ne[i]) {int j = e[i];int tx = j / N, ty = j % N;if (d[tx][ty] > d[x][y] + 1) {d[tx][ty] = d[x][y] + 1;q.offer(tx * N + ty);}}}}public static void main(String[] args) throws IOException {// TODO Auto-generated method stubn = nextInt();m = nextInt();Arrays.fill(h, -1);while (m-- != 0) {int x1 = nextInt();int y1 = nextInt();int x2 = nextInt();int y2 = nextInt();int a = get(x1, y1);int b = get(x2, y2);add(a, b);add(b, a);}bfs();long ans = 0;for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) ans += d[i][j];out.printf("%.2f", ans * 1.0 / (n * n));out.flush();}}

F. 小球称重

在这里插入图片描述
在这里插入图片描述
思路:
思路比较简单,直接上代码吧。

代码:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.HashSet;public class Main {static int n, m;static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));static StreamTokenizer in = new StreamTokenizer(br);public static int nextInt() throws IOException {in.nextToken();return (int) in.nval;}public static void main(String[] args) throws IOException {// TODO Auto-generated method stubString[] nm = br.readLine().split(" ");n = Integer.parseInt(nm[0]);m = Integer.parseInt(nm[1]);HashSet<String> abnormal = new HashSet<>();HashSet<String> tmp = new HashSet<>();HashSet<String> normal = new HashSet<>();while (m-- != 0) {int k = Integer.parseInt(br.readLine());String[] a = br.readLine().split(" ");String[] b = br.readLine().split(" ");HashSet<String> left = new HashSet<String>();HashSet<String> right = new HashSet<String>();for (int i = 0; i < k; i++) {left.add(a[i]);right.add(b[i]);}char op = br.readLine().charAt(0);if (op == '<') {if (abnormal.isEmpty()) abnormal = left;else {tmp = new HashSet<String>();for (String x : left) {if (abnormal.contains(x)) tmp.add(x);}    abnormal = tmp;}} else if (op == '>') {if (abnormal.isEmpty()) abnormal = right;else {tmp = new HashSet<String>();for (String x : right) {if (abnormal.contains(x)) tmp.add(x);}    abnormal = tmp;}} else {normal.addAll(left);normal.addAll(right);for (String x : left) abnormal.remove(x);for (String x : right) abnormal.remove(x);}  }if (abnormal.isEmpty()) out.println(n - normal.size());else out.println(abnormal.size());out.flush();}}

G. 背包与魔法

在这里插入图片描述
在这里插入图片描述
思路分析:
本题是01背包问题的变种,限制条件是最多只能使用一次魔法,求所装物品的最大值。由于使用和不使用有两个状态,因此背包需要再开一维状态,我们用0表示没有使用魔法,用1表示使用魔法。状态表示f[i,j,k]所有用前 i i i 个物品,总体不超过 j j j ,使用/不适用魔法的价值的最大值。本问题的分析过程大部分与01背包问题相同,区别在于判断是否使用魔法。
j > = k − w [ i ] j >= k - w[i] j>=kw[i] 时,更新使用魔法的最大值, f [ i , j , 1 ] = m a x ( f [ i , j , 1 ] , f [ i − 1 , j − k − w [ i ] , 0 ] + 2 ∗ v [ i ] ) f[i, j, 1] = max(f[i, j, 1], f[i - 1, j - k - w[i], 0] + 2 * v[i]) f[i,j,1]=max(f[i,j,1],f[i1,jkw[i],0]+2v[i])

下面是使用闫氏DP分析法的分析过程:
在这里插入图片描述
值得注意的是,由于本题数据范围太大,需要优化为二维才能过,否则会超时

代码:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;public class Main {static final int N = 2010, M = 10010;static int[][] dp = new int[M][2];static int[] v = new int[N], w = new int[N];static int n, m, k;static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));static StreamTokenizer in = new StreamTokenizer(br);public static int nextInt() throws IOException {in.nextToken();return (int) in.nval;}public static void main(String[] args) throws IOException {// TODO Auto-generated method stubn = nextInt();m = nextInt();k = nextInt();for (int i = 1; i <= n; i++) {w[i] = nextInt();v[i] = nextInt();}for (int i = 1; i <= n; i++) {for (int j = m; j >= w[i]; j --) {dp[j][0] = Math.max(dp[j][0], dp[j - w[i]][0] + v[i]);dp[j][1] = Math.max(dp[j][1], dp[j - w[i]][1] + v[i]);if (j >= k + w[i]) dp[j][1] = Math.max(dp[j][1], dp[j - k - w[i]][0] + v[i] * 2);}}out.println(Math.max(dp[m][0], dp[m][1]));out.flush();}}

H. 修路

在这里插入图片描述
在这里插入图片描述
思路:
本题是一个动态规划的题目,可以用闫氏DP分析法分析问题:分析过程如下:
在这里插入图片描述
状态 f ( i , j , k ) f(i, j, k) f(i,j,k) 表示所有走过 a i a_i ai b j b_j bj 的所有走法的集合,属性为 m i n min min

k = 0 k = 0 k=0 时,表示当前在道路 A A A 上;当 k = 1 k = 1 k=1 时,表示当前在道路 B B B 上。

根据 上一个点在 b j b_j bj 还是 a i − 1 a_{i - 1} ai1 上可以划分状态计算,每一类又有两种情况:在道路 A A A 上,在道路 B B B 上,分别取 m i n min min 即可。

重点在于初始化,状态转移方程为:
{ f ( i , j , 0 ) = m i n { f ( i − 1 , j , 0 ) + a i − a i − 1 , f ( i − 1 , j , 1 ) + d i s t ( a i , b j ) } f ( i , j , 1 ) = m i n { f ( i , j − 1 , 0 ) + d i s t ( a i , b j ) , f ( i , j − 1 , 1 ) + b j − b j − 1 } \begin{cases} f(i, j,0) = min\{f(i - 1, j, 0) + a_i - a_{i - 1}, f(i - 1, j, 1) + dist(a_i, b_j) \} \\ f(i, j,1) = min\{f(i, j - 1, 0) + dist(a_i, b_j), f(i , j - 1, 1) +b_j - b_{j - 1} \} \\ \end{cases} {f(i,j,0)=min{f(i1,j,0)+aiai1,f(i1,j,1)+dist(ai,bj)}f(i,j,1)=min{f(i,j1,0)+dist(ai,bj),f(i,j1,1)+bjbj1}

通过 O ( N M ) O(NM) O(NM) 的时间复杂度可以求解。

代码:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.Arrays;public class Main {static final int N = 2010;static int[] a = new int[N], b = new int[N];static double[][][] f = new double[N][N][2]; static int n, m, d;static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));static StreamTokenizer in = new StreamTokenizer(br);public static int nextInt() throws IOException {in.nextToken();return (int) in.nval;}public static void main(String[] args) throws IOException {// TODO Auto-generated method stubn = nextInt();m = nextInt();d = nextInt();a[0] = b[0] = 0;for (int i = 1; i <= n; i++) a[i] = nextInt();for (int i = 1; i <= m; i++) b[i] = nextInt();Arrays.sort(a, 0, n + 1);Arrays.sort(b, 0, m + 1);for (int i = 1; i <= n; i++) {f[i][0][0] = a[i];f[i][0][1] = 1e9;}f[0][1][0] = 1e9;f[0][1][1] = Math.hypot(d, b[1]);for (int i = 2; i <= m; i++) {f[0][i][0] = 1e9;f[0][i][1] = f[0][i - 1][1] + b[i] - b[i - 1];}for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {// 走到aif[i][j][0] = Math.min(f[i - 1][j][0] + a[i] - a[i - 1], f[i - 1][j][1] + Math.hypot(d, a[i] - b[j]));// 走到bjf[i][j][1] = Math.min(f[i][j - 1][0] + Math.hypot(d, a[i] - b[j]), f[i][j - 1][1] + b[j] - b[j - 1]);}}out.printf("%.2f", Math.min(f[n][m][0], f[n][m][1]));out.flush();}}

I. 围栏

在这里插入图片描述
在这里插入图片描述
思路:

这篇关于第十三届蓝桥杯国赛JavaB组题解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/287975

相关文章

SpringBoot使用Apache Tika检测敏感信息

《SpringBoot使用ApacheTika检测敏感信息》ApacheTika是一个功能强大的内容分析工具,它能够从多种文件格式中提取文本、元数据以及其他结构化信息,下面我们来看看如何使用Ap... 目录Tika 主要特性1. 多格式支持2. 自动文件类型检测3. 文本和元数据提取4. 支持 OCR(光学

Java内存泄漏问题的排查、优化与最佳实践

《Java内存泄漏问题的排查、优化与最佳实践》在Java开发中,内存泄漏是一个常见且令人头疼的问题,内存泄漏指的是程序在运行过程中,已经不再使用的对象没有被及时释放,从而导致内存占用不断增加,最终... 目录引言1. 什么是内存泄漏?常见的内存泄漏情况2. 如何排查 Java 中的内存泄漏?2.1 使用 J

JAVA系统中Spring Boot应用程序的配置文件application.yml使用详解

《JAVA系统中SpringBoot应用程序的配置文件application.yml使用详解》:本文主要介绍JAVA系统中SpringBoot应用程序的配置文件application.yml的... 目录文件路径文件内容解释1. Server 配置2. Spring 配置3. Logging 配置4. Ma

Java 字符数组转字符串的常用方法

《Java字符数组转字符串的常用方法》文章总结了在Java中将字符数组转换为字符串的几种常用方法,包括使用String构造函数、String.valueOf()方法、StringBuilder以及A... 目录1. 使用String构造函数1.1 基本转换方法1.2 注意事项2. 使用String.valu

java脚本使用不同版本jdk的说明介绍

《java脚本使用不同版本jdk的说明介绍》本文介绍了在Java中执行JavaScript脚本的几种方式,包括使用ScriptEngine、Nashorn和GraalVM,ScriptEngine适用... 目录Java脚本使用不同版本jdk的说明1.使用ScriptEngine执行javascript2.

Spring MVC如何设置响应

《SpringMVC如何设置响应》本文介绍了如何在Spring框架中设置响应,并通过不同的注解返回静态页面、HTML片段和JSON数据,此外,还讲解了如何设置响应的状态码和Header... 目录1. 返回静态页面1.1 Spring 默认扫描路径1.2 @RestController2. 返回 html2

Spring常见错误之Web嵌套对象校验失效解决办法

《Spring常见错误之Web嵌套对象校验失效解决办法》:本文主要介绍Spring常见错误之Web嵌套对象校验失效解决的相关资料,通过在Phone对象上添加@Valid注解,问题得以解决,需要的朋... 目录问题复现案例解析问题修正总结  问题复现当开发一个学籍管理系统时,我们会提供了一个 API 接口去

Java操作ElasticSearch的实例详解

《Java操作ElasticSearch的实例详解》Elasticsearch是一个分布式的搜索和分析引擎,广泛用于全文搜索、日志分析等场景,本文将介绍如何在Java应用中使用Elastics... 目录简介环境准备1. 安装 Elasticsearch2. 添加依赖连接 Elasticsearch1. 创

Spring核心思想之浅谈IoC容器与依赖倒置(DI)

《Spring核心思想之浅谈IoC容器与依赖倒置(DI)》文章介绍了Spring的IoC和DI机制,以及MyBatis的动态代理,通过注解和反射,Spring能够自动管理对象的创建和依赖注入,而MyB... 目录一、控制反转 IoC二、依赖倒置 DI1. 详细概念2. Spring 中 DI 的实现原理三、

SpringBoot 整合 Grizzly的过程

《SpringBoot整合Grizzly的过程》Grizzly是一个高性能的、异步的、非阻塞的HTTP服务器框架,它可以与SpringBoot一起提供比传统的Tomcat或Jet... 目录为什么选择 Grizzly?Spring Boot + Grizzly 整合的优势添加依赖自定义 Grizzly 作为