HDU 1045 DFS暴搜

Fire Net

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 6229    Accepted Submission(s): 3506

Problem Description

Suppose that we have a square city with straight streets. A map of a city is a square board with n rows and n columns, each representing a street or a piece of wall.

A blockhouse is a small castle that has four openings through which to shoot. The four openings are facing North, East, South, and West, respectively. There will be one machine gun shooting through each opening.

Here we assume that a bullet is so powerful that it can run across any distance and destroy a blockhouse on its way. On the other hand, a wall is so strongly built that can stop the bullets.

The goal is to place as many blockhouses in a city as possible so that no two can destroy each other. A configuration of blockhouses is legal provided that no two blockhouses are on the same horizontal row or vertical column in a map unless there is at least one wall separating them. In this problem we will consider small square cities (at most 4x4) that contain walls through which bullets cannot run through.

The following image shows five pictures of the same board. The first picture is the empty board, the second and third pictures show legal configurations, and the fourth and fifth pictures show illegal configurations. For this board, the maximum number of blockhouses in a legal configuration is 5; the second picture shows one way to do it, but there are several other ways.

Your task is to write a program that, given a description of a map, calculates the maximum number of blockhouses that can be placed in the city in a legal configuration.

Input

The input file contains one or more map descriptions, followed by a line containing the number 0 that signals the end of the file. Each map description begins with a line containing a positive integer n that is the size of the city; n will be at most 4. The next n lines each describe one row of the map, with a ‘.‘ indicating an open space and an uppercase ‘X‘ indicating a wall. There are no spaces in the input file.

Output

For each test case, output one line containing the maximum number of blockhouses that can be placed in the city in a legal configuration.

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

题目意思:

给一个n*n的棋盘,棋盘上有一些墙用X表示,可以在棋盘上放置棋子,条件是任意两个棋子不能用一行或同一列除非两者之间有墙把它们隔开,求最多放置多少个棋子。

思路:

由于题目中说n最大为4,大胆的搜索吧。棋盘的每个位置若是‘.‘&&判断这个位置是否能放,若能num+1,否则向另外一个位置进行前面操作,枚举一遍就行了。

代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <iostream>
 5 using namespace std;
 6
 7
 8 int n;
 9 char map[5][5];
10 int xx[]={0,0,-1,1};
11 int yy[]={1,-1,0,0};
12 int num;
13
14
15 int judge(int x,int y){
16     for(int i=0;i<4;i++){
17         for(int k=1;k<5;k++){
18             int fx=x+k*xx[i];
19             int fy=y+k*yy[i];
20             if(fx>4||fx<1||fy>4||fy<1||map[fx][fy]==‘X‘) break;
21             if(map[fx][fy]==‘@‘) {
22
23                 return 0;
24             }
25         }
26     }
27     return 1;
28 }
29 void dfs(int step){
30     int i, j;
31     for(i=1;i<=n;i++){
32         for(j=1;j<=n;j++){
33             if(map[i][j]==‘.‘&&judge(i,j))
34             {
35                 num=max(num,step+1);
36                 map[i][j]=‘@‘;
37                 dfs(step+1);
38                 map[i][j]=‘.‘;
39             }
40         }
41     }
42
43
44 }
45 main()
46 {
47     int i, j;
48     while(scanf("%d",&n)==1&&n){
49         for(i=1;i<=n;i++) scanf("%s",map[i]+1);
50         num=0;
51         dfs(0);
52         printf("%d\n",num);
53     }
54 }

HDU 1045 DFS暴搜

时间: 2024-10-08 10:32:18

HDU 1045 DFS暴搜的相关文章

[HDU 5135] Little Zu Chongzhi&#39;s Triangles (dfs暴搜)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5135 题目大意:给你n条边,选出若干条边,组成若干个三角形,使得面积和最大.输出最大的面积和. 先将边从小到大排序,这样前面的两条边加起来如果不大于第三条边就可以跳出,这是一个存在性条件. dfs(int idx,int now,int cnt,int nowmax)代表我当前处理的是第idx条边,已经加入边集的有cnt条边,当前的边的长度和为now,组成的最大面积和为nowmax. 暴力枚举每个三

HDU 4284 Travel Folyd预处理+dfs暴搜

题意:给你一些N个点,M条边,走每条边要花费金钱,然后给出其中必须访问的点,在这些点可以打工,但是需要先拿到证书,只可以打一次,也可以选择不打工之直接经过它.一个人从1号点出发,给出初始金钱,问你能不能访问所以的点,并且获得所以证书. 题解:目标是那些一定要访问的点,怎么到达的我们不关心,但是我们关系花费最少的路径,而且到达那个点后是一定要打工的,如果只是经过,那么在求花费最少的路径的时候已经考虑过了. 因此先用Folyd求出各个点直接的最短路径,由于N很小,又只要求出一个解,所以直接dfs暴搜

[ACM] hdu 4403 A very hard Aoshu problem (DFS暴搜数字)

A very hard Aoshu problem Problem Description Aoshu is very popular among primary school students. It is mathematics, but much harder than ordinary mathematics for primary school students. Teacher Liu is an Aoshu teacher. He just comes out with a pro

HDU 5012 bfs暴搜

Dice Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 243    Accepted Submission(s): 135 Problem Description There are 2 special dices on the table. On each face of the dice, a distinct number wa

[HDU 1427]速算24点(DFS暴搜)

题目连接:  http://acm.hdu.edu.cn/showproblem.php?pid=1427 思路:简单的DFS,dfs(sum,next,p)表示当前已经算出的值是sum,括号中算出的值是next,当前使用的卡片下标为p,实际上是把括号外和括号内的两部分值分成sum和next来处理了. 直觉告诉我们4个数只需要一层括号参与运算就够了,不会也不必用多重括号改变运算顺序,因此上面的dfs思路是正确的. 那么对于下一张卡片,有两种处理方式: 1.把next算入sum中,下一张卡片成

HDU 1045 (DFS搜索)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1045 题目大意:在不是X的地方放O,所有O在没有隔板情况下不能对视(横行和数列),问最多可以放多少个O. 解题思路: 题目规模比较小(4*4),可以DFS解决. 对于一个点,要么放,要么不放. 放的话条件必须是上下左右四个方向扫到边界且不首先碰到X. 可以只对放的点进行标记,而对于不放的点不进行标记,这样当dep>n*n的时候及时return就行了. 注意每次dfs只需要按顺序考虑一个点,而不要同

HDU 5339 Untitled(暴搜)

Untitled Problem Description There is an integer $a$ and $n$ integers $b_1, \ldots, b_n$. After selecting some numbers from $b_1, \ldots, b_n$ in any order, say $c_1, \ldots, c_r$, we want to make sure that $a \ mod \ c_1 \ mod \ c_2 \ mod \ldots \ m

HDU 1045 dfs

Fire Net Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 11742    Accepted Submission(s): 7048 Problem Description Suppose that we have a square city with straight streets. A map of a city is a

Hdu 4016 Magic Bitwise And Operation (暴搜 dfs)

题目大意: 在n个数中选取k个数,是他们的按位与最小. 思路分析: 开始往dp想,但是这道题是不满足子问题的. 当前的值最小,但是丢掉了和后面的1错开的最多的状态. 暴搜的剪枝: 1.与后面所有的树相与都比ans小,剪掉,因为越与越小. 2.先将所有的数排序,先取小的. 3.ans可以不断更新,不需要达到k的时候更新,原因和1相同. #include <cstdio> #include <iostream> #include <cstring> #include <