1. 程式人生 > >zoj 1002 Fire Net 碉堡的最大數量【DFS】

zoj 1002 Fire Net 碉堡的最大數量【DFS】

文件的 分享 設置 net 兩個 開放 std class OS

題目鏈接

題目大意:

假設我們有一個正方形的城市,並且街道是直的。城市的地圖是n行n列,每一個單元代表一個街道或者一塊墻。

碉堡是一個小城堡,有四個開放的射擊口。四個方向是面向北、東、南和西。在每一個口子上有一架機關槍。

假設子彈能夠穿過任何距離,並且摧毀路上的碉堡。另一方面,子彈不能穿越墻。

我們的目標是在城市裏設置足夠多的碉堡,並且任何兩個碉堡都不會互相摧毀。正確的配置是沒有兩個碉堡在相同的水平行或者垂直列上,除非碉堡之間有墻把它們分開。在這個問題中,我們將使用小的方形城市(最多4*4),它包含了墻,並且子彈不能穿越。

接下來的圖片顯示五張城市地圖,第1張圖片是空的布局,第2張和第3張圖片顯示了合法的配置,第4和第5張圖片顯示了非法的配置。對於這樣的地形來說,碉堡的最大數是5;第2張圖片顯示了這個配置方案,但還有其他的配置方案。

技術分享圖片

你的任務是寫一個程序,在給出的地圖描述下,計算城市中可以合法放置的碉堡的最大數。

輸入文件包含一個或者多個地圖描述,0作為文件的結束。每個地圖描述首行是城市的尺寸n,n最大為4。接下來的n行描述了地圖的每一行,符號“."代表開放區域,大寫的X代表墻。輸入文件中沒有空格。

每一個測試用例,最後輸出一行為合法放置碉堡的最大數。

Sample input:

4
.X..
....
XX..
....
2
XX
.X
3
.X.
X.X
.X.
3
...
.XX
.XX
4
....
....
....
....
0

Sample output:

5
1
5
2
4

#include <stdio.h>
int
n, res,max; int chess[10][10]; int juge(int x, int y) { int i, j; for (i = y; i >= 0; i--) { if (chess[x][i] == 1)return 0; if (chess[x][i] == 2)break; } for (i = y; i < n; i++) { if (chess[x][i] == 1)return 0; if (chess[x][i] == 2)break; }
for (i = x; i >= 0; i--) { if (chess[i][y] == 1)return 0; if (chess[i][y] == 2)break; } for (i = x; i < n; i++) { if (chess[i][y] == 1)return 0; if (chess[i][y] == 2)break; } return 1; } void dfs() { int i, j; if (res > max)max = res; for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { if (!chess[i][j] && juge(i, j)) { chess[i][j] = 1; //選擇在該點放碉堡 res++; dfs(); chess[i][j] = 0; //選擇在該點不放碉堡 這種感覺有點像動態規劃的思想 res--; } } } } int main() { char str[10]; int i, j; while (scanf("%d", &n) != EOF, n) { max = 0; for (i = 0; i < n; i++) { scanf("%s", str); for (j = 0; j < n; j++) { if (str[j] == X)chess[i][j] = 2; else chess[i][j] = 0; } } res = 0; dfs(); printf("%d\n", max); } return 0; }


2018-03-31

zoj 1002 Fire Net 碉堡的最大數量【DFS】