zoj1002
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.
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.
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
直接上代码吧
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <list>
#define OPEN 1
#define CASTLE 2
#define BLOCK 3
#define WALL 4
// summary: 用贪心原理找到一个影响地图最小的城堡的位置
// param in: map[] 输入的地图. n 地图大小.
// param out: min_x,min_y 得出的放置的城堡的x,y坐标
// return: true 找到了合适的位置. false 没有可以放置城堡的地方了
#define MAX_POINT 10000 // 哨兵数
bool FindMinInfluencePosition(int map[][], int n, int &min_x, int &min_y)
{
int min_point = MAX_POINT; // 赋哨兵值
min_x = min_y = ; for (int y = ; y < n; y++)
{
for (int x = ; x < n; x++)
{
if ( map[y][x] == OPEN)
{
int curr_point = ; // 向上
for (int j = y - ; j >= && map[j][x] != WALL; j--)
{
if ( map[j][x] == OPEN)
curr_point++;
} // 向下
for (int j = y + ; j < n && map[j][x] != WALL; j++)
{
if ( map[j][x] == OPEN)
curr_point++;
} // 向左
for (int j = x - ; j >= && map[y][j] != WALL; j--)
{
if ( map[y][j] == OPEN)
curr_point++;
} // 向右
for (int j = x + ; j < n && map[y][j] != WALL; j++)
{
if ( map[y][j] == OPEN)
curr_point++;
} if (curr_point < min_point)
{
min_point = curr_point;
min_x = x;
min_y = y;
}
}
}
} // 检测是否放置了城堡
if (min_point != MAX_POINT)
return true;
else
return false; } // summary: 根据位置放置城堡,在地图上标记出来
// param in: map[] 输入的地图. n 地图大小. x, y 放置的城堡的位置
void PlaceCastle(int map[][], int n, int x, int y)
{
map[y][x] = CASTLE; // 向上
for (int j = y - ; j >= && map[j][x] != WALL; j--)
{
map[j][x] = BLOCK;
} // 向下
for (int j = y + ; j < n && map[j][x] != WALL; j++)
{
map[j][x] = BLOCK;
} // 向左
for (int j = x - ; j >= && map[y][j] != WALL; j--)
{
map[y][j] = BLOCK;
} // 向右
for (int j = x + ; j < n && map[y][j] != WALL; j++)
{
map[y][j] = BLOCK;
}
} int main ()
{
int map[][];
std::list<int> answer;//构造函数
int n;
char c; // Read the data
std::cin>>n;
while (n != )
{
// Read map data
for (int y = ; y < n; y++)
{
for (int x = ; x < n; x++)
{
std::cin>>c;
if (c == '.')
map[y][x] = OPEN;
else
map[y][x] = WALL;
}
} // Processing maps
int castle_number = ;
int min_x, min_y;
while (FindMinInfluencePosition(map, n, min_x, min_y) == true )
{
castle_number++;
PlaceCastle(map, n, min_x, min_y);
} // Record the data
answer.push_back(castle_number); // Enter the next number
std::cin>>n;
} // The number of output
for (std::list<int>::iterator it=answer.begin() ; it != answer.end(); ++it)
std::cout <<*it<<"\n"; return ;
} //菜鸟一枚,代码来自大神的博客,只是记录自己的学习,具体那一篇后来没找到,若有侵犯,楼主请留言
zoj1002的更多相关文章
- ZOJ1002 —— 深度优先搜索
ZOJ1002 —— Fire net Time Limit: 2000 ms Memory Limit: 65536 KB Suppose that we have a square city wi ...
- zoj1002 Fire Net
Fire Net Time Limit: 2 Seconds Memory Limit: 65536 KB Suppose that we have a square city with s ...
- C++二分图匹配基础:zoj1002 FireNet 火力网
直接给出题目吧... 问题 D(1988): [高级算法]火力网 时间限制: 1 Sec 内存限制: 128 MB 题目描述 给出一个N*N的网格,用'.'表示空地,用'X'表示墙.在网格上放碉堡,可 ...
- OJ题目分类
POJ题目分类 | POJ题目分类 | HDU题目分类 | ZOJ题目分类 | SOJ题目分类 | HOJ题目分类 | FOJ题目分类 | 模拟题: POJ1006 POJ1008 POJ1013 P ...
- 牛人的ACM经验 (转)
一:知识点 数据结构: 1,单,双链表及循环链表 2,树的表示与存储,二叉树(概念,遍历)二叉树的 应用(二叉排序树,判定树,博弈 ...
- ACM算法锦集
一:知识点 数据结构: 1,单,双链表及循环链表 2,树的表示与存储,二叉树(概念,遍历)二叉树的 应用(二叉排序树,判定树,博弈树,解答树等) 3,文件操作(从文本文件中读入数据并输出到文本文 件中 ...
随机推荐
- Python查询Redis中的Key
今日,大哥让我查下项目的在线用户量,听到这个消息顿时懵逼了,在线用户量,这个该怎么查????想到项目中的登陆用户缓存信息Token都存放在Redis中,是不是可以根据Redis中Token的个数大致估 ...
- 【动画演示】:JS 作用域链不在话下
作者:Lydia Hallie译者:前端小智来源:dev 点赞再看,养成习惯 本文 GitHub https://github.com/qq44924588... 上已经收录,更多往期高赞文章的分类, ...
- php 增删改查范例(3)
编辑页面edit.php: <?php$id=$_GET['id'];$db= new mysqli('localhost','root','root','db_0808');$sql=&quo ...
- iOS收起键盘
在UIViewController中收起键盘,有四种代码方式: 1.让相应的控件放弃第一响应者 /** 放弃第一响应者 */ [self.nameTextField resignFirstRespon ...
- 常用的UI控件
关于本文:作为一名iOS软件工程师,熟练规范的使用常用的UI控件是必备的基础技能. 指示器(UIActivityIndicatorView)----转动的等待小菊花 提醒对话框(UIAlertView ...
- 深入理解 Python 中的装饰器
装饰器本质上也是函数,接收函数对象来作为参数,并在装饰器的内部来调用接受的函数对象完成相关的函数调用,也可以这样理解 ,为了方便在几个不同函数调用之前或者完成相关的统一操作,注意是完成统一的操作, ...
- VNC怎么和宿主机共享粘贴板
VNC怎么和宿主机共享粘贴板 假设目标主机是linux,终端主机是windows(就是在windows上使用VNC登陆linux) 在linux中执行vncconfig -nowin& 在li ...
- JS实现复制信息到剪贴板
copy 当用户通过浏览器UI启动复制操作并响应允许的document.execCommand('copy')调用时触发copy事件. copy事件可作用于任何可被选中或可编辑的元素,如body.di ...
- 使用c#调用API入门
使用C#调用windows API入门 一:入门,直接从 C# 调用 DLL 导出 其实我们的议题应该叫做C#如何直接调用非托管代码,通常有2种方法: 1. 直接调用从 DLL 导出的函数. 2 ...
- springboot#配置文件处理
1. 加载自定义属性文件 2. 通过bean聚合相关属性 1. 在启动类上通过如下注解可以加载自定义的属性文件 @PropertySource(value = {"classpath:pro ...