大家好,我是snippet,今天是我们刷蓝桥真题的第二十五天,今天的内容包含搜索+贪心+动态规划,下面的我今天的题解
目录
一、全球变暖
题目链接:
全球变暖 - 蓝桥云课 (lanqiao.cn)
题目内容:
解题思路:
代码:
二、调手表
题目链接:调手表 - 蓝桥云课 (lanqiao.cn)
题目内容:
解题思路:
代码:
三、铺设道路
题目链接:铺设道路 - 蓝桥云课 (lanqiao.cn)
题目内容:
解题思路:
代码:
四、搬砖
题目链接:搬砖 - 蓝桥云课 (lanqiao.cn)
题目内容:
解题思路:
代码:
题目描述
你有一张某海域 NxN 像素的照片,"."表示海洋、"#"表示陆地,如下所示:
.......
.##....
.##....
....##.
..####.
...###.
.......
其中"上下左右"四个方向上连在一起的一片陆地组成一座岛屿。例如上图就有 2 座岛屿。
由于全球变暖导致了海面上升,科学家预测未来几十年,岛屿边缘一个像素的范围会被海水淹没。具体来说如果一块陆地像素与海洋相邻(上下左右四个相邻像素中有海洋),它就会被淹没。
例如上图中的海域未来会变成如下样子:
.......
.......
.......
.......
....#..
.......
.......
请你计算:依照科学家的预测,照片中有多少岛屿会被完全淹没。
输入描述
第一行包含一个整数 N (1≤N≤1000)。
以下 N 行 N 列代表一张海域照片。
照片保证第 1 行、第 1 列、第 N 行、第 N 列的像素都是海洋。、
输出一个整数表示答案。
输入输出样例
示例
输入
7
.......
.##....
.##....
....##.
..####.
...###.
.......输出
1
运行限制
- 最大运行时间:1s
- 最大运行内存: 256M
package 蓝桥杯31天真题冲刺.Day25;
import java.io.*;
/**
* @author snippet
* @data 2023-03-28
* 全球变暖-蓝桥云课
*/
// 搜索 dfs/bfs
public class T1_全球变暖 {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
static int n,sum,cnt;// n表示海域的长宽 sum表示岛屿的个数 cnt表示不会被完全淹没的岛屿的个数
static boolean flag;// flag用来表示该岛屿是不是会被完全淹没 true表示不会 false表示会被完全淹没
static int N = 1010;
static char[][] c = new char[N][N];// 二维数组c存海域的组成 "."表示海洋 "#"表示陆地
static boolean[][] visit = new boolean[N][N];// 二维数组visit表示这个位置是否被遍历过 false表示未被遍历 true表示遍历过了
static int[] dx = {0, 0, 1, -1};
static int[] dy = {1, -1, 0, 0};
// 对每一片岛屿进行搜索
static void dfs(int x, int y) {
visit[x][y] = true;
if (c[x+dx[0]][y+dy[0]] == '#' && c[x+dx[1]][y+dy[1]] == '#'
&& c[x+dx[2]][y+dy[2]] == '#' && c[x+dx[3]][y+dy[3]] == '#') flag = true;
for (int i = 0; i < 4; i++) {
int x1 = x + dx[i];
int y1 = y + dy[i];
if (x1 >= 0 && x1 < n && y1 >= 0 && y1 < n && c[x1][y1] == '#' && !visit[x1][y1]) {
dfs(x1, y1);
}
}
}
public static void main(String[] args) throws IOException {
String[] s = br.readLine().split(" ");
n = Integer.parseInt(s[0]);
for (int i = 0; i < n; i++) {
s = br.readLine().split(" ");
c[i] = s[0].toCharArray();
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (c[i][j] == '#' && !visit[i][j]) {
flag = false;
sum++;
dfs(i, j);
// 如果这片岛屿不会被完全淹没,则cnt++
if (flag) cnt++;
}
}
}
// pw.println(sum + " " + cnt);
pw.println(sum - cnt);
pw.flush();
br.close();
}
}
题目描述
小明买了块高端大气上档次的电子手表,他正准备调时间呢。
在 M78 星云,时间的计量单位和地球上不同,M78 星云的一个小时有 n 分钟。
大家都知道,手表只有一个按钮可以把当前的数加一。在调分钟的时候,如果当前显示的数是 0 ,那么按一下按钮就会变成 1,再按一次变成 2 。如果当前的数是 n−1,按一次后会变成 0。
作为强迫症患者,小明一定要把手表的时间调对。如果手表上的时间比当前时间多 1,则要按 n−1 次加一按钮才能调回正确时间。
小明想,如果手表可以再添加一个按钮,表示把当前的数加 �k 该多好啊......
他想知道,如果有了这个 +k 按钮,按照最优策略按键,从任意一个分钟数调到另外任意一个分钟数最多要按多少次。
注意,按 +k 按钮时,如果加 k 后数字超过 n−1,则会对 n 取模。
比如,n=10,k=6 的时候,假设当前时间是 0,连按 2 次 +k 按钮,则调为 2。
输入描述
一行两个整数 n,k (0
输出描述
输出一行一个整数,表示按照最优策略按键,从一个时间调到另一个时间最多要按多少次。
输入输出样例
示例
输入
5 3
输出
2
样例解释
如果时间正确则按 0 次。否则要按的次数和操作系列之间的关系如下:
1:+1
2:+1, +1
3:+3
4:+3, +1
运行限制
- 最大运行时间:1s
- 最大运行内存: 256M
package 蓝桥杯31天真题冲刺.Day25;
import java.io.*;
import java.util.LinkedList;
import java.util.Queue;
/**
* @author snippet
* @data 2023-03-28
* 调手表-蓝桥云课
*/
public class T2_调手表 {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
static int n,k,max;
static int N = 100100;
static boolean[] visit = new boolean[N];
static Queue queue = new LinkedList<>();
public static void main(String[] args) throws IOException {
String[] s = br.readLine().split(" ");
n = Integer.parseInt(s[0]);
k = Integer.parseInt(s[1]);
queue.offer(0);
visit[0] = true;
while (!queue.isEmpty()) {
int size = queue.size();
max++;
while (size-- > 0) {
int x = queue.poll();
if (!visit[(x + 1) % n]) {
visit[(x + 1) % n] = true;
queue.offer((x + 1) % n);
}
if (!visit[(x + k) % n]) {
visit[(x + k) % n] = true;
queue.offer((x + k) % n);
}
}
}
// 减去初始为0的时候
pw.println(max - 1);
pw.flush();
br.close();
}
}
题目描述
春春是一名道路工程师,负责铺设一条长度为 n 的道路。
铺设道路的主要工作是填平下陷的地表。整段道路可以看作是 n 块首尾相连的区域,一开始,第 i 块区域下陷的深度为 di 。
春春每天可以选择一段连续区间 [L,R],填充这段区间中的每块区域,让其下陷深度减少 1。在选择区间时,需要保证,区间内的每块区域在填充前下陷深度均不为 0 。
春春希望你能帮他设计一种方案,可以在最短的时间内将整段道路的下陷深度都变为 0 。
输入描述
输入包含两行,第一行包含一个整数 n,表示道路的长度。
第二行包含 n 个整数,相邻两数间用一个空格隔开,第 i 个整数为 di 。
其中,1≤n≤105,0≤di≤104 。
输出描述
输出仅包含一个整数,即最少需要多少天才能完成任务。
输入输出样例
示例
输入
6
4 3 2 5 3 5输出
9
样例解释
一种可行的最佳方案是,依次选择:[1,6]、[1,6]、[1,2]、[1,1]、[4,6]、[4,4]、[4,4]、[6,6]、[6,6]。
运行限制
- 最大运行时间:1s
- 最大运行内存: 256M
package 蓝桥杯31天真题冲刺.Day25;
import java.io.*;
/**
* @author snippet
* @data 2023-03-28
* 铺设道路-蓝桥云课
*/
// 贪心
public class T3_铺设道路 {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
static int n,ans;
static int N = 100100;
static int[] arr = new int[N];
public static void main(String[] args) throws IOException {
String[] s = br.readLine().split(" ");
n = Integer.parseInt(s[0]);
s = br.readLine().split(" ");
for (int i = 1; i <= n; i++) {
arr[i] = Integer.parseInt(s[i-1]);
}
// 贪心 --> 当该位置为0时 不可以跟其他位置一起填充
// 那我们可以将每个位置往前减 如果该位置的下陷深度大于前一位置 那填充差值
// 因为非差值可以通过前面的相同的值来填充
for (int i = 1; i <= n; i++) {
ans += Math.max(0, arr[i] - arr[i-1]);
}
pw.println(ans);
pw.flush();
br.close();
}
}
问题描述
这天,小明在搬砖。
他一共有 n 块砖, 他发现第 i 砖的重量为 wi, 价值为 vi 。他突然想从这些 砖中选一些出来从下到上堆成一座塔, 并且对于塔中的每一块砖来说, 它上面 所有砖的重量和不能超过它自身的价值。
他想知道这样堆成的塔的总价值(即塔中所有砖块的价值和)最大是多少。
输入格式
输入共 n+1 行, 第一行为一个正整数 n, 表示砖块的数量。
后面 n 行, 每行两个正整数 wi,vi 分别表示每块砖的重量和价值。
输出格式
一行, 一个整数表示答案。
样例输入
5
4 4
1 1
5 2
5 5
4 3样例输出
10
样例说明
选择第 1、2、4 块砖, 从上到下按照 2、1、4 的顺序堆成一座塔, 总价值 为 4+1+5=10
评测用例规模与约定
对于 20% 的数据, 保证 n≤10;
对于 100% 的数据, 保证 n≤1000;wi≤20;vi≤20000 。
运行限制
- 最大运行时间:1s
- 最大运行内存: 512M
package 蓝桥杯31天真题冲刺.Day25;
import java.io.*;
import java.util.Arrays;
import java.util.Comparator;
/**
* @author snippet
* @data 2023-03-28
* 搬砖-蓝桥云课
*/
// 动态规划+排序
public class T4_搬砖 {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
static int n,ans;
static int N = 1010;
static int[][] arr = new int[N][2];
static int[] f = new int[N * 20];
public static void main(String[] args) throws IOException {
String[] s = br.readLine().split(" ");
n = Integer.parseInt(s[0]);
for (int i = 1; i <= n; i++) {
s = br.readLine().split(" ");
arr[i][0] = Integer.parseInt(s[0]);
arr[i][1] = Integer.parseInt(s[1]);
}
Arrays.sort(arr,1,n+1, new Comparator() {
@Override
public int compare(int[] o1, int[] o2) {
return (o1[0] + o1[1]) - (o2[0] + o2[1]);
}
});
for (int i = 1; i <= n; i++) {
int w = arr[i][0];
int v = arr[i][1];
for (int j = 20000; j >= w; j--) {
if (v >= j - w) f[j] = Math.max(f[j], f[j - w] + v);
}
}
for (int i = 0; i <= 20000; i++) {
ans = Math.max(ans, f[i]);
}
pw.println(ans);
pw.flush();
br.close();
}
}