题干:

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

解题报告:

这题水啊,数据范围4*4,比赛的时候直接dfs一发。找准dfs定义的状态的含义,不难写,有点类似八皇后的递归思路。

二分图显然要把原始图分别按行和列缩点。建图:横竖分区。同一列相连的空地同时看成一个点,显然这样的区域不能够同时放两个点。这些点作为二分图的X部。同理在对所有的行用相同的方法缩点,作为Y部。

连边的条件是两个区域有相交部分(即'.'的地方)。最后求最大匹配就是答案。

AC代码:

#include<bits/stdc++.h>
using namespace std;
int n,ans;
char maze[10][10];
bool bk[10][10];
bool ok(int x,int y) {for(int i = x; i>=1; i--) {if(maze[i][y] == 'X') break;if(bk[i][y] == 1) return 0;}for(int i = y; i>=1; i--) {if(maze[x][i] == 'X') break;if(bk[x][i] == 1) return 0;}return 1;
}
void dfs(int x,int y,int cur) {if(x == n && y == n) {if(maze[x][y] == '.' &&ok(x,y)) cur++;ans = max(ans,cur);return ;}if(y == n) {if(maze[x][y] == '.' && ok(x,y)) {bk[x][y]=1;
//          make(x,y);dfs(x+1,1,cur+1);bk[x][y]=0;}dfs(x+1,1,cur);}else {if(maze[x][y] == '.' && ok(x,y)) {bk[x][y]=1;dfs(x,y+1,cur+1);bk[x][y]=0;}dfs(x,y+1,cur);}}
int main()
{while(~scanf("%d",&n) ) {if(n == 0) break;memset(bk,0,sizeof bk);ans=0;for(int i = 1; i<=n; i++) {scanf("%s",maze[i]+1);}dfs(1,1,0);printf("%d\n",ans);       }return 0 ;
}

AC代码2:(二分图)

#include<bits/stdc++.h>using namespace std;
char maze[55][55];
int visx[55][55],visy[55][55];
int n;
int totx,toty;
bool line[55][55];
int nxt[55];
bool used[55];
bool find(int x) {for(int i = 1; i<=toty; i++) {if(line[x][i] && used[i]==0) {used[i]=1;if(nxt[i] == -1 || find(nxt[i])) {nxt[i] = x;return 1;}}}return 0;
}
int match() {int sum = 0;memset(nxt,-1,sizeof nxt);for(int i = 1; i<=totx; i++) {memset(used,0,sizeof used);if(find(i)) sum++;}return sum;
}
int main()
{while(~scanf("%d",&n)) {if(n == 0) break;memset(visx,0,sizeof visx);memset(visy,0,sizeof visy);memset(line,0,sizeof line);totx=toty=0;for(int i = 1; i<=n; i++) scanf("%s",maze[i]+1);for(int i = 1; i<=n; i++) {for(int j = 1; j<=n; j++) {if(maze[i][j] == '.') {if(visx[i][j-1]!=0) visx[i][j] = visx[i][j-1];else visx[i][j] = ++totx;if(visy[i-1][j]!=0) visy[i][j] = visy[i-1][j];else visy[i][j] = ++toty;}}}for(int i = 1; i<=n; i++) {for(int j = 1; j<=n; j++) {if(maze[i][j] == '.') {line[visx[i][j]][visy[i][j]] = 1;
//                  printf("%d %d\n",visx[i][j],visy[i][j]);}}}printf("%d\n",match());} return 0 ;
}

【HDU - 1045】Fire Net (dfs 或二分图)相关推荐

  1. hdu 1045 Fire Net

    经典建模. #include<cstdio> #include<cstring> #include<algorithm> using namespace std; ...

  2. HDU 2444 The Accomodation of Students 二分图匹配

    HDU 2444 The Accomodation of Students 二分图匹配 题目来源: HDU 题意: 给出学生数n和关系数m,接下来给出m个关系. 要求将学生分成两部分,每一部分不能有互 ...

  3. (匹配)Fire Net --hdu --1045

    链接: http://acm.hdu.edu.cn/showproblem.php?pid=1045 http://acm.hust.edu.cn/vjudge/contest/view.action ...

  4. hdu 杭电 1045 Fire Net

    题意:地图中最多能放多少炮台. 解法:深搜. ac代码: View Code #include<iostream> using namespace std;char map[8][8]; ...

  5. HDU 4685 Prince and Princess(二分图+强连通分量)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4685 题意:给出n个王子和m个公主.每个王子有一些自己喜欢的公主可以匹配.设最大匹配为M.那么对于每个 ...

  6. hdu 5325 Crazy Bobo dfs

    // hdu 5325 Crazy Bobo // // 题目大意: // // 给你一棵树,树上每一个节点都有一个权值w,选择尽可能多的节点, // 这些节点相互联通,而且依照权值升序排序之后得到节 ...

  7. CodeForces - 817F Graph and String(dfs判二分图)

    题目链接:点击查看 题目大意:给出一张图,现在要求给出一种合适的染色方案,使得: 只能用 ' a ' , ' b ' , ' c ' 进行染色 有边相连的两个点的颜色要么相同,要么相邻,不能是 ' a ...

  8. CodeForces - 1354E Graph Coloring(dfs判断二分图+dp)

    题目链接:点击查看 题目大意:给出一个由 n 个点和 m 条边组成的无向图,要求给 n 个点赋值为 1 . 2 或 3 ,需要满足以下条件: 每个点都需要被赋值 权值为 1 的点共 n1 个 权值为 ...

  9. HDU - 3829 Cat VS Dog(最大独立集-二分图最大匹配)

    题目链接:点击查看 题目大意:给出n只狗和m只猫,现在有p个小朋友,每个小朋友都有一只喜欢的猫和一只不喜欢的狗,或者有一只喜欢的狗和一只不喜欢的猫,如果一个小朋友喜欢的动物还在,不喜欢的动物走了,那么 ...

最新文章

  1. 为什么经营婚姻要像热恋一样
  2. Unity-数学2-四元数
  3. IPropertySet接口
  4. plsql 记录型变量
  5. ZJOI2018 Round2 游记
  6. fedora20 安装ror
  7. react router v4 简介
  8. Spring框架----Spring的环绕通知
  9. CSS3秘笈复习:第一章第二章第三章
  10. Linux下处理BOM头和^M的简单方法
  11. tcp/ip协议详解
  12. 【毕设狗】【单片机毕业设计】基于单片机的红外非接触测温设计-实物设计
  13. FIRST集和 FOLLOW集的计算
  14. 软考程序员常见问题答疑
  15. 数据外连接 LEFT OUT JOIN 的用法
  16. SQL Server 基础操作(一)安装数据库
  17. java 角色管理代码_后台管理系统-角色管理模块
  18. 阅读笔记 - Horizon Zero Dawn 广袤世界中的玩家漫游
  19. 2021.5.22 Python爬虫实战:效率办公,从下载文献开始...
  20. 坚持#第251天~凡哥作业over

热门文章

  1. 使用scikit中的聚类
  2. [剑指offer]面试题第[28]题[Leedcode][JAVA][第101题][对称二叉树][队列][递归]
  3. 扩展欧几里得算法 POJ 1061
  4. linux查询内存条个数,linux下查看内存条数及每根内存大小的实现方法(推荐)
  5. java multimap 序列化_C++ JSON库的使用
  6. 计算机中函数counta表示,excel中counta函数的使用方法
  7. Spring 4 MVC 单元测试例子
  8. java切面1.6需要的包_Java技术 AspectJ
  9. Socket的send函数在执行时报EAGAIN的错误
  10. WinCE内核裁减(中文字体)及字库和内核的分离