Fire Net
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 8877 Accepted Submission(s): 5139
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 XXX.X.X 3 .X. .X..XX3 ... .XX 4........ .... ....0
Sample Output
51254
题目大意:有一个n行n列的网格,可以往里面填炮台,炮台的炮可以沿着行或者列发射,但是不可以穿过墙。现在问最多可以放多少个炮台,使得它们不会打到对方。
思路:一开始的思路不对,比较混乱,想着从上往下搜索整个网格,能放就放上,并做标记,遇到墙就清除本行本列的标记。但是这样很难实现,递归的边界不明确,而且有个问题就是只能做到从第一个开始搜索直到结束,不能返回上一次有分叉的地方。
后来参考了别人的代码(附上网址:http://www.acmerblog.com/hdu-1045-fire-net-1308.html),感觉思路清晰多了。。。用一个函数来判断某个格点是否可以放炮台,即先判断一下它的左边,如果遇到的第一个是炮台,直接返回0,若遇到的第一个是墙,就退出循环,上方同理。然后再递归,具体见代码。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int visc[5],n,maxn;
char grid[5][5];
int judge(int k)//判断该格点是否可以放炮台
{
int r=k/n,c=k%n;
int i;
for(i=c;i>=0;i--)
{
if(grid[r][i]=='X')break;
else if(grid[r][i]=='@')return 0;
}
for(i=r;i>=0;i--)
{
if(grid[i][c]=='X')break;
else if(grid[i][c]=='@')return 0;
}
return 1;
}
void dfs(int k,int cnt)
{
if(k==n*n)
{
if(maxn<cnt)maxn=cnt;
return;
}
if(grid[k/n][k%n]=='.'&&judge(k))
{
grid[k/n][k%n]='@';
dfs(k+1,cnt+1);
grid[k/n][k%n]='.';
}
dfs(k+1,cnt);
}
int main()
{
while(scanf("%d",&n) != EOF)
{
if(n==0)break;
for(int i=0;i<n;i++)
{
scanf("%s",grid[i]);
}
maxn=-1;
dfs(0,0);
printf("%d\n",maxn);
}
return 0;
}
这题做完之后还有一个地方需要总结,就是表示一个点的方式可以只用一个数,如这题中的k,比如说一个点的坐标是(x,y),k=x*n+y,n为每行的列数。要恢复成原来的坐标就是x=k/n,y=k%n就可以了。这题似乎还有一种做法。。。以后再更新好了

博客讲述了如何解决HDU 1045 Fire Net问题,该问题涉及在一个n行n列的网格中放置炮台,避免炮台互相射击。作者最初尝试了从上到下搜索并标记的方法,但发现困难重重。后来参考他人代码,采用判断格点是否可以放置炮台的函数,通过检查左右和上方是否有炮台或墙壁来优化解决方案。博客还提到用一个数字k表示坐标(x, y),并讨论了其他可能的解题方法。"
112941279,10546271,蓝桥杯单片机数码管动态显示程序设计,"['单片机开发', '中断控制', '数码管显示', '蓝桥杯竞赛', 'C语言编程']

316

被折叠的 条评论
为什么被折叠?



