原题链接:蓝桥杯2018年第九届真题-迷宫与陷阱
解题思路:
BFS
每次移动判断路程是否小于status[y][x]中的值,如果小于,则找到更短路径,保存并且将该点状态入队列,继续搜索。
if (step < status[y][x]) { status[y][x] = step; queue.add(new Integer[] { x, y, step, energy }); }
搜索到'#'时停止;搜索到'%'时增加k并且不能让它再次进入'%'将其设置为'#'(因为第一次进入'%'即是最短路程,再次进入并没有意义,并且会增加时间复杂度(剪枝思想));搜索到'X'时如果有has_energy就继续,否则停止;搜索到'.'时继续;
if ('#' == maze[y][x]) { break; } else if ('%' == maze[y][x]) { energy = k; maze[y][x] = '#'; } else if ('X' == maze[y][x]) { if (!has_energy) break; } else if ('.' == maze[y][x]) { }
注意事项:
无
参考代码:
import java.util.LinkedList; import java.util.Scanner; /** * Hello world! */ public class Main { static boolean move(byte[][] maze, int[][] status, int n, int k, LinkedList<Integer[]> queue, int x, int y, int step, int energy, boolean has_energy) { do { if ('#' == maze[y][x]) { break; } else if ('%' == maze[y][x]) { energy = k; maze[y][x] = '#'; } else if ('X' == maze[y][x]) { if (!has_energy) break; } else if ('.' == maze[y][x]) { } if (energy > 0) { if (step < status[y][x]) status[y][x] = step; queue.add(new Integer[] { x, y, step, energy }); } else { if (step < status[y][x]) { status[y][x] = step; queue.add(new Integer[] { x, y, step, energy }); } } if (x == n - 1 && y == n - 1) { return true; } } while (false); return false; } public static void main(String[] args) { Scanner sc = new Scanner(System.in); // N x N {min, {min, energy}} byte[][] maze; int[][] status; int n = sc.nextInt(); int k = sc.nextInt(); status = new int[n][n]; maze = new byte[n][n]; sc.nextLine(); for (int i = 0; i < n; ++i) { String line = sc.nextLine(); char[] l = line.toCharArray(); for (int j = 0; j < l.length; ++j) { maze[i][j] = (byte) l[j]; status[i][j] = Integer.MAX_VALUE; } } LinkedList<Integer[]> queue = new LinkedList<Integer[]>(); status[0][0] = 0; queue.add(new Integer[] { 0, 0, 0, '%' == maze[0][0] ? k : 0 }); int curr_step = 0, n2 = n * n; while (curr_step < n2 && !queue.isEmpty()) { Integer[] curr = queue.remove(); int x, y, step = curr[2] + 1, energy = curr[3] - 1; x = curr[0]; y = curr[1]; boolean has_energy = energy >= 0; if (energy < 0) energy = 0; curr_step = step; // Move up; x = curr[0]; y = curr[1] - 1; if (y >= 0) { if (move(maze, status, n, k, queue, x, y, step, energy, has_energy)) { System.out.println(step); return; } } // Move right; x = curr[0] + 1; y = curr[1]; if (x < n) { if (move(maze, status, n, k, queue, x, y, step, energy, has_energy)) { System.out.println(step); return; } } // Move down; x = curr[0]; y = curr[1] + 1; if (y < n) { if (move(maze, status, n, k, queue, x, y, step, energy, has_energy)) { System.out.println(step); return; } } // Move left; x = curr[0] - 1; y = curr[1]; if (x >= 0) { if (move(maze, status, n, k, queue, x, y, step, energy, has_energy)) { System.out.println(step); return; } } } System.out.println(-1); return; } }
0.0分
2 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复