Fire Net

来源:互联网 发布:zara淘宝没有了 编辑:程序博客网 时间:2024/06/15 21:36

Fire Net

Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other)

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

//题目意思:造尽可能多的blockhouses,要满足同一行、同一列不能有2个,除非中间有墙隔开。

//思路:见注释

#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <cmath>#include <cstdlib>#include <algorithm>using namespace std;#define MAX 10int n;int ans;char map[MAX][MAX];int check(int x, int y)  //从该点左边、上面进行查找 //x是行数,y是列数{    int i;    for (i = y; i >= 0; i--) //上    {        if (map[x][i] == 'X') //如果有格挡,说明该列满足条件            break;        else if (map[x][i] == 'B') //如果该列已有未格挡的blockhouse,说明该点不能造,直接return false            return 0;    }    for (i = x; i >= 0; i--) //左    {        if (map[i][y] == 'X') //如果有格挡,说明该行满足条件            break;        else if (map[i][y] == 'B') //如果该行已有未格挡的blockhouse,说明该点不能造,直接return false            return 0;    }    return 1;}void dfs(int pos, int sum){    int x = pos / n; //行数    int y = pos%n; //列数    if (pos == n*n)  //遍历完整个图的时候    {        //如果这种情况能造更多的blockhouse,那么把sum的值传给全局变量ans        if (sum > ans)         {            ans = sum;        }        return;    }    if (map[x][y] == '.'&&check(x, y) == 1) //如果这个点可以造blockhouse且符合条件    {        map[x][y] = 'B'; //假设在这点造blockhouse        dfs(pos + 1, sum + 1);  //blockhouse的数量+1,搜索下一个位置,直到把在这点造blockhouse的情况全部遍历完        map[x][y] = '.'; //假设不在这点造blockhouse(地图还原)    }    dfs(pos + 1, sum); //假设不在这点造blockhouse,搜索下一个位置,直到把在这点造blockhouse的情况全部遍历完}int main(){    int i, j;    while (scanf("%d", &n) && n)    {        getchar(); //别忘了这个...坑...不然下面第一个scanf会读到一个'\n'        for (i = 0; i < n; i++)        {            for (j = 0; j < n; j++)            {                scanf("%c", &map[i][j]);            }            getchar(); //同理        }        ans = 0;        dfs(0, 0); //从头开始遍历        printf("%d\n", ans);    }    return 0;}