B - Fire Net
Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u
Submit
Status
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表示墙,现在往地图上放入尽量多的碉堡,并且使他们不能相互攻击,求能放入最大的碉堡数量。
很明显要用搜索的方法做,但是这道题被分到贪心的题目类别下。然后就郁闷了一上午来想这个题。。非常不爽。。
搜索时枚举的条件:该点没有被访问过,且该位置可以放下炮台(没有同行同列的炮台,或者不被攻击到),用MAX标记出最大可能出现的炮台数量。
在计算炮台有没有被攻击到时,从枚举的位置往上、下、左、右四个位置比较,遇到有墙时单个方向就可以停止比对,遇到有炮台就说明该位置被攻击到,不能放下炮台,如果四个方向均没有问题,就说明该位置是可以放下炮台的。
搜索题目还是没有练熟……为了憋出这几行代码,花了整整一个早上的时间。。心疼呐。
#include <cstdio>
#include<iostream>
#include <cstring>
#include <algorithm>
using namespace std;
char G[20][20];
int visit[20][20];
int N;
int maxV = 0,cnt = 0;
bool Find(int x,int y)
{
if (G[x][y] == 'X') return 0;
else
{
for(int i = y;i>=1;i--)
{
if(G[x][i] =='O')
return 0;
if(G[x][i] =='X')
break;
}
for(int i = y; i<=N;i++)
{
if(G[x][i]=='O')
return 0;
if(G[x][i] =='X')
break;
}
for(int i = x; i>=1;i--)
{
if(G[i][y]=='O')
return 0;
if(G[i][y]=='X')
break;
}
for(int i = x; i<=N;i++)
{
if(G[i][y]=='O')
return 0;
if(G[i][y]=='X')
break;
}
return 1;
}
return 0;
}
void dfs()
{
cnt = max(cnt,maxV);
for(int i =1; i<=N;i++)
{
for(int j = 1; j<=N;j++)
{
if( !visit[i][j] && Find(i,j) ) //如果x的位置没有访问过,且该位置可以放
{
// printf("%d %d\n",i,j);
visit[i][j]=1;
maxV++;
G[i][j] = 'O';
dfs();
visit[i][j] = 0;
G[i][j] = '.';
maxV--;
}
}
}
}
int main()
{
while(cin>>N)
{
if (N == 0) break;
for(int i =1; i <=N; i++)
for(int j = 1; j <=N; j++)
cin>>G[i][j];
cnt = 0;
maxV = 0;
dfs();
printf("%d\n",cnt);
}
return 0;
}