1. 程式人生 > 實用技巧 >【藍橋杯】邊界為1的最大子方陣的優化

【藍橋杯】邊界為1的最大子方陣的優化

優化方法:

直接判斷某個頂點是否為矩陣的左上角。通過輔助陣列。該陣列負責記錄該頂點(包含自身)的右方,和下方1的個數。可以看作是改二維陣列中又包含一個二元組。

1 1 1 0
1 1 0 1
1 1 0 1
0 1 1 1

其輔助陣列為(右,下)

(3,1) (4,1) (1,1) (0,0)
(2,2) (1,3) (0,0) (1,3)
(2,1) (1,2) (0,0) (1,2)
(0,0) (3,1) (2,1) (1,1)

加了底紋的部分,(2,2)表示包括自身在內右邊又2個1,向下有2個1。所以正方形的上邊和左邊已證明可以構成邊框全為1;

        (2,1)2表示向右有2個1

,構成正方形的下邊;(1,3)3表示向下有3個1,構成正方形的右邊。所以邊框全是1的最大正方形的邊長長度為2。

滿足這四個部分,就證明可以構成邊界全為1的最大正方形。

該部分就是替換上一篇中的內層while的思路。

難點在於輔助陣列generateHelpRec的建立。

  1.格式為(右,下),所以建立會從右下角開始,一行一行的向上走;

  2.可以先初始化最後一行,需要注意的就是陣列下標不要越界;

程式碼如下:

  1 public class case4_1 {
  2 
  3     public static void main(String[] args) {
  4         /*
int arr[][] = { 5 { 1, 1, 1,1}, 6 { 1, 0, 1,1}, 7 { 1, 1, 1,1}, 8 { 1, 0, 1,0}, 9 }; 10 */ 11 int arr[][] = { 12 { 1, 0, 1, 1,1 }, 13 { 1, 1, 1, 1,1 }, 14 { 1, 1, 1, 0,1 }, 15 { 1, 1, 1, 1,1 },
16 { 1, 1, 1, 1,1 }, 17 }; 18 generateHelpRec(arr, arr.length); 19 // printArr(rec, arr.length);//該方法主要是為了檢測三維陣列建立的是否正確。 20 int res = max(arr, arr.length); 21 System.out.println(res); 22 23 } 24 25 private static void printArr(int[][][] rec2, int N) { 26 for (int i = 0; i < N; i++) { 27 for (int j = 0; j < N; j++) { 28 System.out.print("(" + rec[i][j][0] + "," + rec[i][j][1] + ")" 29 + "\t"); 30 } 31 System.out.println(); 32 } 33 } 34 35 static int[][][] rec; 36 37 // 建立輔助表;三維陣列 38 private static void generateHelpRec(int[][] arr, int N) { 39 rec = new int[N][N][2]; 40 // 先初始化最後一行; 41 int row = N - 1; 42 for (int j = N - 1; j >= 0; j--) { 43 int value = arr[row][j]; 44 if (value == 1) { 45 if (j == N - 1)// 右邊1的個數,j增加 46 rec[row][j][0] = 1; 47 else 48 rec[row][j][0] = rec[row][j + 1][0] + 1; 49 50 rec[row][j][1] = 1; 51 } 52 53 } 54 row--; 55 // 構建三維表 56 for (int i = row; i >= 0; i--) { 57 for (int j = N - 1; j >= 0; j--) { 58 int value = arr[i][j]; 59 if (value == 1) { 60 if (j == N - 1) { 61 rec[i][j][0] = 1; 62 } else { 63 rec[i][j][0] = rec[i][j + 1][0] + 1; 64 } 65 rec[i][j][1] = rec[i + 1][j][1] + 1; 66 } 67 } 68 } 69 70 } 71 72 static int max(int[][] matrix, int N) { 73 int n = N; 74 while (n > 0) { 75 for (int i = 0; i < N; i++) { 76 if (i + n > N) 77 break; 78 l3: for (int j = 0; j < N; j++) { 79 if (j + n > N) 80 break; 81 82 if (check(i, j, n) == true) 83 return n; 84 85 } 86 } 87 88 n--; 89 90 } 91 92 return 0; 93 } 94 95 private static boolean check(int i, int j, int n) { 96 if (rec[i][j][0] >= n && rec[i][j][1] >= n && rec[i + n - 1][j][0] >= n 97 && rec[i][j + n - 1][1] >= n) 98 return true; 99 return false; 100 } 101 }

上述程式碼輸出 :4

歡迎大家一起來交流。