• bfs提高系列之陨石下落


    P2895 [USACO08FEB] Meteor Shower S - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

    主要思路如下,

    1:首先贝萨可以跑到牧场外,牧场牧场仅仅300*300那么大,

    2:其次跑到牧场外不一定是最优解,可能牧场内某一点可能是最优的

    整体思路是从起点的bfs,我们一开始记录一下所有会被陨石砸中的点,一旦我们bfs跑到一个点没被任何陨石砸中,那么我们就输出这个时间。同时我们要在每个时间段刷新一下下落的陨石,来判断这个格子能不能走。

    来一波总思路吧

    首先我们输入每个流星下落的地点和时间,把调用方法把所有可能会被变成不可走的点标记上,

    接着我们把流行按照时间先后放入队列排好序。我们要知道我们要让流星先于我们一个时间单位坠落,也就是说我们在时间0的时候就要让时间1的流行陨落,为什么呢。你想呀,假如说你在时间0时走到了1号地点,现在时间为1了,这时我们在启动流星下落,万一流星下落到1号位置,你不就被砸死了吗,所以我们要在走前先把下一步流行落下。在开始走时,先落下0时辰的流行,在落1时间的流星。我们在落完流星后,我们开始往四周试探,如果这个点没被走过或者流星砸过,我们把它入优先队列的同时,判断一下他是不是最后的那个安全点,是就输出时间顺便把标记answer改为0,不是就接着走.记住流星不能超过牧场边界,而人可以,所以贝萨在走时没给他限制小于300。

    最后如果answer始终没改变,那就证明贝萨没走出。输出-1

    代码有注释:

    1. import java.io.BufferedReader;
    2. import java.io.IOException;
    3. import java.io.InputStreamReader;
    4. import java.io.PrintWriter;
    5. import java.math.BigInteger;
    6. import java.math.MathContext;
    7. import java.util.ArrayList;
    8. import java.util.Arrays;
    9. import java.util.Collections;
    10. import java.util.Comparator;
    11. import java.util.Iterator;
    12. import java.util.LinkedList;
    13. import java.util.PriorityQueue;
    14. import java.util.Scanner;
    15. import java.util.TreeMap;
    16. import java.util.TreeSet;
    17. public class Main {
    18. public static void main(String[] args) throws NumberFormatException, IOException {
    19. Scanner sc=new Scanner(System.in);
    20. BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
    21. String[] aStrings=br.readLine().split(" ");
    22. int a=Integer.parseInt(aStrings[0]);
    23. int b;
    24. for(b=0;b//预处理
    25. String[] bStrings=br.readLine().split(" ");
    26. int c=Integer.parseInt(bStrings[0]);
    27. int d=Integer.parseInt(bStrings[1]);
    28. int e=Integer.parseInt(bStrings[2]);
    29. ll1.add(new liuxing(c, d, e));
    30. jieguo[c][d]=1;
    31. chuliliuxing(c, d);//
    32. }
    33. Collections.sort(ll1);
    34. LinkedList ll2=new LinkedList<>();
    35. liuxing lx1=new liuxing(0, 0, 0);
    36. ll2.add(lx1);
    37. int f=0;
    38. jiance(0);
    39. visited[0][0]=1;
    40. while(ll2.size()!=0) {
    41. liuxing lx2=ll2.remove();
    42. jiance(lx2.time+1);
    43. int b1=lx2.x;
    44. int c1=lx2.y;
    45. int d1=lx2.time;
    46. for(int a1=0;a1<4;a1++) {
    47. int x1=xx[a1]+b1;
    48. int y1=yy[a1]+c1;
    49. if(x1>=0&&y1>=0&&visited[x1][y1]==0) {
    50. visited[x1][y1]=1;
    51. //System.out.println("AAA"+x1+" "+y1+" " +d1);
    52. ll2.add(new liuxing(x1, y1, d1+1));
    53. if(jieguo[x1][y1]==0) {
    54. answer=0;
    55. //System.out.println(x1+" "+y1);
    56. System.out.println(d1+1);
    57. return;
    58. }
    59. }
    60. }
    61. }
    62. if(answer==Integer.MAX_VALUE) {
    63. System.out.println("-1");
    64. }
    65. }
    66. public static int answer=Integer.MAX_VALUE;
    67. public static LinkedList ll1=new LinkedList<>();
    68. public static int[][] jieguo=new int[350][350];//此数组记录最终被陨石点燃的点
    69. public static int[][] visited=new int[350][350];//此数组记录按时间不可走的点
    70. public static int[] xx= {-1,1,0,0};//四个方位
    71. public static int[] yy= {0,0,-1,1};
    72. public static void jiance(int a) {//此方法的作用是按照时间将四周的领域点燃来模拟流行下降的问题。
    73. while(true) {
    74. if(ll1.size()==0) {
    75. break;
    76. }
    77. if(ll1.get(0).time!=a) {
    78. break;
    79. }
    80. if(ll1.size()!=0) {
    81. if(ll1.get(0).time==a) {
    82. int c;
    83. for(c=0;c<4;c++) {
    84. int d=ll1.get(0).x+xx[c];
    85. int e=ll1.get(0).y+yy[c];
    86. if(d<0||d>300||e<0||e>300) {
    87. continue;
    88. }
    89. visited[d][e]=1;
    90. }
    91. }
    92. ll1.remove();
    93. }
    94. }
    95. }
    96. public static void chuliliuxing(int a,int b) {//主要记录流星下落后的点及其周围被点燃的点
    97. int c;
    98. for(c=0;c<4;c++) {
    99. int d=a+xx[c];
    100. int e=b+yy[c];
    101. if(d<0||d>300||e<0||e>300) {//限制范围在农场之内。
    102. continue;
    103. }
    104. jieguo[d][e]=1;
    105. }
    106. }
    107. }
    108. class liuxing implements Comparable{//流行类,主要记录流行下落的地点时间,并按时间排序
    109. int x;
    110. int y;
    111. int time;
    112. public liuxing(int x, int y, int time) {
    113. super();
    114. this.x = x;
    115. this.y = y;
    116. this.time = time;
    117. }
    118. @Override
    119. public int compareTo(liuxing o) {
    120. // TODO Auto-generated method stub
    121. return this.time-o.time;
    122. }
    123. }

  • 相关阅读:
    Node.js(7)-node的http模块
    微信小程序组件所在页面的生命周期
    华为云大数据BI赋能企业数字化发展
    03-vue-cli-项目创建
    【vue后台管理系统】基于Vue+Element-UI+ECharts开发通用管理后台(上)
    arm push/pop/b/bl汇编指令
    4.2冰达机器人:视觉实例-机器人视觉循线、视觉实例-调整循线颜色
    量化交易如何通过Python进行技术分析?
    python在导入模块时,即import时究竟有哪些动作?
    数位dp,338. 计数问题
  • 原文地址:https://blog.csdn.net/m0_73862548/article/details/133145764