当前位置:   article > 正文

冲刺蓝桥杯Java b组——合并区域(DFS深度优先)_蓝桥杯合并区域

蓝桥杯合并区域

今天刚好除夕,先祝大家除夕快乐。作者也希望各位读者在新的一年事业有成,健健康康。

作者最近在准备蓝桥杯java b组,因此在刷相关的题目,希望这里的分享可以帮助到大家。


前言

有关DFS的相关题目及java实现。


一、问题分析

1.1问题描述

        小蓝在玩一款种地游戏。现在他被分配给了两块大小均为N*N的正方形区域。这两块区域都按照N*N的规格进行了均等划分,划分成了若干块面积相同的小区域,其中每块小区域要么是岩石,要么就是土壤,在垂直或者水平方向上相邻的土壤可以组成一块土地。现在小蓝想要对这两块区域沿着边缘进行合并,他想知道合并以后可以得到的最大的一块土地的面积是多少(土地的面积就是土地中土壤小区域的块数)

1.2输入格式:

        第一行一个整数。

        接下来N行表示第一块区域,每行N个值为0或1的的整数,相邻的整数之间用空格进行分隔。值为0或1的整数,相邻的整数之间用空格进行分隔。值为0表示这块区域为演示,值为1表示这块区域为土壤。

1.3输出格式

        一个整数表示将两块区域合并后可以产生的最大土地的面积。

1.4问题分析

        这是一个典型的DFS或者BFS问题,就是将两个n*n的矩阵以任意的形式拼接。其实就是求所有连接的1的最大数量。只要便利所有的拼接情况写一个递归就好了。

        然后将程序分成4部分:

第一部分:录入数据

第二部分:将矩阵旋转(一个xuanzhuan函数)

第三部分:将举证拼接(2个矩阵拼接然后补成一个大矩形,空的地方填写0)

第四部分:求最大土地面积(DFS)

二、解体题步骤

2.1录入数据

        简单的两个新建二维数组,然后两个for循环写入

  1. Scanner sc = new Scanner(System.in);
  2. int n = sc.nextInt();
  3. int map1[][] = new int[n][n];
  4. int map2[][] = new int[n][n];
  5. for(int i=0;i<n;i++) {
  6. for(int j=0;j<n;j++) {
  7. map1[i][j]=sc.nextInt();
  8. }
  9. }
  10. for(int i=0;i<n;i++) {
  11. for(int j=0;j<n;j++) {
  12. map2[i][j]=sc.nextInt();
  13. }
  14. }

2.2旋转矩阵部分

  1. public static int[][] xuanzhuan(int map[][]){
  2. int n = map.length;
  3. int map_90[][] = new int[n][n];
  4. for(int i=0;i<n;i++) {
  5. for(int j=0;j<n;j++) {
  6. map_90[j][n-i-1] = map[i][j];//这个归纳可以证明的
  7. }
  8. }
  9. return map_90;
  10. }

        这里的推到难点作者用笔记给大家看,其实难的还是归纳,一行一列归纳很快可以得出结论a[i][j]->a[j][n-i-1]。 

2.3矩阵合并部分 

    

  1. public static int[][] hebing(int map1[][],int map2[][],int count) {//count是矩阵1的右上角和左下角的位移差
  2. int n = map1.length;
  3. int map[][];
  4. if(count>=n) {//map1在左上角
  5. map = new int[count][2*n];
  6. for(int i=0;i<count;i++) {
  7. for(int j=0;j<2*n;j++) {
  8. if(i<n&&j<n) {
  9. map[i][j]=map1[i][j];
  10. }
  11. else if(i>=count-n&&j>=n) {
  12. map[i][j]=map2[i+n-count][j-n];
  13. }
  14. else {
  15. map[i][j] = 0;
  16. }
  17. }
  18. }
  19. }
  20. else {//map1在左下角
  21. map = new int[2*n-count][2*n];
  22. for(int i=0;i<2*n-count;i++) {
  23. for(int j=0;j<2*n;j++) {
  24. if(i<n&&j>=n) {
  25. map[i][j]=map2[i][j-n];
  26. }
  27. else if(i>=n-count&&j<n) {
  28. map[i][j]=map1[i-n+count][j];
  29. }
  30. else {
  31. map[i][j]=0;
  32. }
  33. }
  34. }
  35. }
  36. return map;
  37. }

    

2.4求最大土地面积(DFS)

        其实很简单就是找到有1的地方然后慢慢往周围找,如果有1,num就++,防止重复查找,找过的地方就变成0,这样子就可以加快速度,然后四处延申直到找完为止(设计到了迭代)。

  1. public static int max_area(int[][]map) {
  2. int max = 0;
  3. for(int i=0;i<map.length;i++) {
  4. for(int j=0;j<map[0].length;j++) {
  5. if(map[i][j]==1) {
  6. int num = map_dfs(i,j,map);
  7. if(max<num) {
  8. max=num;
  9. }
  10. }
  11. }
  12. }
  13. return max;
  14. }
  15. private static int map_dfs(int i, int j, int[][] map) {
  16. int num = 0;
  17. if(map[i][j]==0) {
  18. return num;
  19. }
  20. else if(map[i][j]==1) {
  21. map[i][j]=0;
  22. num++;
  23. }
  24. if(i>0&&map[i-1][j]==1) {
  25. num+=map_dfs(i-1,j,map);
  26. }
  27. if(i<map.length-1&&map[i+1][j]==1) {
  28. num+=map_dfs(i+1,j,map);
  29. }
  30. if(j>0&&map[i][j-1]==1) {
  31. num+=map_dfs(i,j-1,map);
  32. }
  33. if(j<map[0].length-1&&map[i][j+1]==1) {
  34. num+=map_dfs(i,j+1,map);
  35. }
  36. return num;
  37. }

 2.5总代码

  1. package 蓝桥杯备赛;
  2. import java.util.Scanner;
  3. public class 合并区域 {
  4. public static void main(String[] args) {
  5. Scanner sc = new Scanner(System.in);
  6. int n = sc.nextInt();
  7. int map1[][] = new int[n][n];
  8. int map2[][] = new int[n][n];
  9. for(int i=0;i<n;i++) {
  10. for(int j=0;j<n;j++) {
  11. map1[i][j]=sc.nextInt();
  12. }
  13. }
  14. for(int i=0;i<n;i++) {
  15. for(int j=0;j<n;j++) {
  16. map2[i][j]=sc.nextInt();
  17. }
  18. }
  19. int map1_90[][] = xuanzhuan(map1);
  20. int map1_180[][] = xuanzhuan(map1_90);
  21. int map1_270[][] = xuanzhuan(map1_180);
  22. int map2_90[][] = xuanzhuan(map2);
  23. int map2_180[][] = xuanzhuan(map2_90);
  24. int map2_270[][] = xuanzhuan(map2_180);
  25. int maps1[][][] = {map1,map1_90,map1_180,map1_270};
  26. int maps2[][][] = {map2,map2_90,map2_180,map2_270};
  27. int count = 2*n-1;
  28. int max = 0;
  29. int maps[][][][]= {maps1,maps2};
  30. while(count>0) {
  31. for(int i=0;i<4;i++) {
  32. for(int j=0;j<4;j++) {
  33. if(max<max_area(hebing(maps[0][i],maps[1][j],count))) {
  34. max = max_area(hebing(maps[0][i],maps[1][j],count));
  35. }
  36. }
  37. }
  38. count--;
  39. }
  40. System.out.print(max);
  41. }
  42. //顺势针转90度
  43. public static int[][] xuanzhuan(int map[][]){
  44. int n = map.length;
  45. int map_90[][] = new int[n][n];
  46. for(int i=0;i<n;i++) {
  47. for(int j=0;j<n;j++) {
  48. map_90[j][n-i-1] = map[i][j];//这个归纳可以证明的
  49. }
  50. }
  51. return map_90;
  52. }
  53. public static int[][] hebing(int map1[][],int map2[][],int count) {//count是矩阵1的右上角和左下角的位移差
  54. int n = map1.length;
  55. int map[][];
  56. if(count>=n) {//map1在左上角
  57. map = new int[count][2*n];
  58. for(int i=0;i<count;i++) {
  59. for(int j=0;j<2*n;j++) {
  60. if(i<n&&j<n) {
  61. map[i][j]=map1[i][j];
  62. }
  63. else if(i>=count-n&&j>=n) {
  64. map[i][j]=map2[i+n-count][j-n];
  65. }
  66. else {
  67. map[i][j] = 0;
  68. }
  69. }
  70. }
  71. }
  72. else {//map1在左下角
  73. map = new int[2*n-count][2*n];
  74. for(int i=0;i<2*n-count;i++) {
  75. for(int j=0;j<2*n;j++) {
  76. if(i<n&&j>=n) {
  77. map[i][j]=map2[i][j-n];
  78. }
  79. else if(i>=n-count&&j<n) {
  80. map[i][j]=map1[i-n+count][j];
  81. }
  82. else {
  83. map[i][j]=0;
  84. }
  85. }
  86. }
  87. }
  88. return map;
  89. }
  90. public static int max_area(int[][]map) {
  91. int max = 0;
  92. for(int i=0;i<map.length;i++) {
  93. for(int j=0;j<map[0].length;j++) {
  94. if(map[i][j]==1) {
  95. int num = map_dfs(i,j,map);
  96. if(max<num) {
  97. max=num;
  98. }
  99. }
  100. }
  101. }
  102. return max;
  103. }
  104. private static int map_dfs(int i, int j, int[][] map) {
  105. int num = 0;
  106. if(map[i][j]==0) {
  107. return num;
  108. }
  109. else if(map[i][j]==1) {
  110. map[i][j]=0;
  111. num++;
  112. }
  113. if(i>0&&map[i-1][j]==1) {
  114. num+=map_dfs(i-1,j,map);
  115. }
  116. if(i<map.length-1&&map[i+1][j]==1) {
  117. num+=map_dfs(i+1,j,map);
  118. }
  119. if(j>0&&map[i][j-1]==1) {
  120. num+=map_dfs(i,j-1,map);
  121. }
  122. if(j<map[0].length-1&&map[i][j+1]==1) {
  123. num+=map_dfs(i,j+1,map);
  124. }
  125. return num;
  126. }
  127. }

总结

        DFS的实现其实是我今天的一个难度。总的来说实现还是通过递归实现的。

        至于作者之前为什么断更了,是因为作者在这年找到了女朋友。也非常感谢女朋友的支持,她几乎每次都会点赞我的文章。文末放一张我和女朋友的照片,嘻嘻!

下学期开始作者会逐渐的更新爬虫js逆向包括验证码啥的,希望大家多多关注哦!!!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/460881
推荐阅读
相关标签
  

闽ICP备14008679号