標籤:數字 ade nbsp lock 接下來 res mil stat idt
目錄
1 問題描述
2 解決方案
1 問題描述問題描述
如所示,3 x 3 的格子中填寫了一些整數。
+--*--+--+
|10* 1|52|
+--****--+
|20|30* 1|
*******--+
| 1| 2| 3|
+--+--+--+
我們沿著圖中的星號線剪開,得到兩個部分,每個部分的數字和都是60。
本題的要求就是請你編程判定:對給定的m x n 的格子中的整數,是否可以分割為兩個部分,使得這兩個地區的數字和相等。
如果存在多種解答,請輸出包含左上方格子的那個地區包含的格子的最小數目。
如果無法分割,則輸出 0。
輸入格式
程式先讀入兩個整數 m n 用空格分割 (m,n<10)。
表示表格的寬度和高度。
接下來是n行,每行m個正整數,用空格分開。每個整數不大於10000。
輸出格式輸出一個整數,表示在所有解中,包含左上方的分割區可能包含的最小的格子數目。範例輸入13 3
10 1 52
20 30 1
1 2 3範例輸出13範例輸入24 3
1 1 1 1
1 30 80 2
1 1 1 100範例輸出210
2 解決方案
具體代碼如下:
import java.util.Scanner;public class Main { public static int n, m; public static int SUM; public static int[][] step = {{-1,0},{1,0},{0,-1},{0,1}}; public static int[][] map; public static int[][] visited; public static int result = 10000; public void testDFS(int x, int y, int[][] v) { //完成剪下後的另一部分是否是連通的 v[x][y] = 2; for(int i = 0;i < 4;i++) { int x1 = x + step[i][0]; int y1 = y + step[i][1]; if(x1 < 0 || x1 >= n || y1 < 0 || y1 >= m) continue; if(v[x1][y1] == 0) testDFS(x1, y1, v); } } public void dfs(int startX, int startY, int count, int sum) { if(sum == SUM / 2) { int x = 0, y = 0, step = 0; int[][] v = new int[n][m]; for(int i = 0;i < n;i++) { for(int j = 0;j < m;j++) { if(visited[i][j] == 0) { x = i; y = j; } v[i][j] = visited[i][j]; } } testDFS(x, y, v); for(int i = 0;i < n;i++) for(int j = 0;j < m;j++) if(v[i][j] == 2) step++; if(step + count == n * m) { if(visited[0][0] == 1) result = Math.min(result, count); else { result = Math.min(result, step); } } return; } else if(sum > SUM / 2) return; for(int i = 0;i < 4;i++) { int x1 = startX + step[i][0]; int y1 = startY + step[i][1]; if(x1 < 0 || x1 >= n || y1 < 0 || y1 >= m) continue; if(visited[x1][y1] == 1) continue; visited[x1][y1] = 1; count++; sum += map[x1][y1]; dfs(x1, y1, count, sum); sum -= map[x1][y1]; count--; visited[x1][y1] = 0; } } public static void main(String[] args) { Main test = new Main(); Scanner in = new Scanner(System.in); m = in.nextInt(); n = in.nextInt(); map = new int[n][m]; SUM = 0; for(int i = 0;i < n;i++) { for(int j = 0;j < m;j++) { map[i][j] = in.nextInt(); SUM += map[i][j]; } } if(SUM % 2 == 0) { for(int i = 0;i < n;i++) { for(int j = 0;j < m;j++) { visited = new int[n][m]; int sum = map[i][j]; int count = 1; visited[i][j] = 1; test.dfs(i, j, count, sum); } } if(result != 10000) System.out.println(result); else System.out.println("-1"); } else System.out.println("-1"); }}
演算法筆記_196:曆屆試題 剪格子(Java)