HDU 1045 Fire Net(搜索剪枝)
http://acm.split.hdu.edu.cn/showproblem.php?pid=1045
http://acm.hdu.edu.cn/showproblem.php?pid=1045
题目链接(总有一个可以点开)……
题意:给出一张地图,上面只有两种字符(.和X),X相当于无法穿透的墙。问这张地图上最多可以放置多少个互不攻击的子弹……


第一反应是搜索,然而后来看到网上有些大神说这是二分图匹配……看来还是要研究下。
我剪枝的思路:对每个点设置所有关联的点(上下左右四个方向直到被墙挡住),每个点依次存放关联点。这样每次搜索的时候就可以省一些时间,同时降低编程复杂度。
每次搜到的子弹数都用ans[]存下(ans[i]true意为可能存在大于i的可行方案),操作的时候二维表变成一位表(这样方便)。
例如有张4*4的表:
(0,0)->(0)
(0,1)->(1)
...
(1,0)->(4)
...
(3,3)->(15)
具体就是这样。
代码如下:
#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <functional> using namespace std; #define REP(i,n) for(int i(0); i < (n); ++i)
#define rep(i,a,b) for(int i(a); i <= (b); ++i)
#define dec(i,a,b) for(int i(a); i >= (b); --i)
#define for_edge(i,x) for(int i = H[x]; i; i = X[i]) #define LL long long
#define ULL unsigned long long
#define MP make_pair
#define PB push_back
#define FI first
#define SE second
#define INF 1 << 30 const int N = + ;
const int M = + ;
const int Q = + ;
const int A = + ; vector <int> v[Q];
int c[A][A], h[A][A];
char st[Q];
bool f[Q], ans[Q];
int n, num, ret; void dfs(int k, int low, bool * f){
ans[k] = true; bool now = true; REP(i, n * n) if (!f[i]) { now = false; break; } if (now) return; int d[Q];
REP(j, num) d[j] = f[j]; rep(i, low, num - ) if (!f[i]){ f[i] = true; REP(j, v[i].size()) f[v[i][j]] = true; dfs(k + , low + , f); REP(j, num) f[j] = d[j];}
} int main(){
#ifndef ONLINE_JUDGE
freopen("test.txt", "r", stdin);
freopen("test.out", "w", stdout);
#endif while (~scanf("%d", &n), n){
REP(i, n){ scanf("%s", st); REP(j, n) c[i][j] = st[j] == '.' ? : ; }
//REP(i, n){ REP(j, n) putchar(c[i][j] + 48); putchar(10);}
int cnt = ; REP(i, n) REP(j, n) h[i][j] = cnt++;
REP(i, n * n + ) v[i].clear(); num = n * n;
REP(i, n) REP(j, n) if (!c[i][j]){
rep(k, j + , n - ){ if (c[i][k]) break; v[h[i][j]].PB(h[i][k]); }
rep(k, i + , n - ){ if (c[k][j]) break; v[h[i][j]].PB(h[k][j]); }
dec(k, j - , ){ if (c[i][k]) break; v[h[i][j]].PB(h[i][k]); }
dec(k, i - , ){ if (c[k][j]) break; v[h[i][j]].PB(h[k][j]); }
}
//REP(i, n) REP(j, n){ printf("%d %d: ", i, j); REP(k, v[h[i][j]].size()) printf("%d ", v[h[i][j]][k]); puts("");} puts("");
memset(ans, false, sizeof ans); REP(i, n) REP(j, n) f[h[i][j]] = c[i][j];
REP(i, n) REP(j, n) if (!c[i][j]) dfs(, h[i][j], f);
ret = ; dec(i, num, ) if (ans[i]){ ret = i; break;}
printf("%d\n", ret);
} return ; }
HDU上 0MS..手动胜利!!(数据好像蛮弱的)
HDU 1045 Fire Net(搜索剪枝)的更多相关文章
- HDOJ(HDU).1045 Fire Net (DFS)
HDOJ(HDU).1045 Fire Net [从零开始DFS(7)] 点我挑战题目 从零开始DFS HDOJ.1342 Lotto [从零开始DFS(0)] - DFS思想与框架/双重DFS HD ...
- hdu 1045 Fire Net(最小覆盖点+构图(缩点))
http://acm.hdu.edu.cn/showproblem.php?pid=1045 Fire Net Time Limit:1000MS Memory Limit:32768KB ...
- HDU 1045(Fire Net)题解
以防万一,题目原文和链接均附在文末.那么先是题目分析: [一句话题意] 给定大小的棋盘中部分格子存在可以阻止互相攻击的墙,问棋盘中可以放置最多多少个可以横纵攻击炮塔. [题目分析] 这题本来在搜索专题 ...
- HDU 1045 Fire Net 【连通块的压缩 二分图匹配】
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1045 Fire Net Time Limit: 2000/1000 MS (Java/Others) ...
- HDU 1045 Fire Net(dfs,跟8皇后问题很相似)
传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1045 Fire Net Time Limit: 2000/1000 MS (Java/Others) ...
- HDU 1045——Fire Net——————【最大匹配、构图、邻接矩阵做法】
Fire Net Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit Sta ...
- HDU 1045 Fire Net 状压暴力
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1045 Fire Net Time Limit: 2000/1000 MS (Java/Others) ...
- HDU 1045 Fire Net 二分图建图
HDU 1045 题意: 在一个n*n地图中,有许多可以挡住子弹的墙,问最多可以放几个炮台,使得炮台不会相互损害.炮台会向四面发射子弹. 思路: 把行列分开做,先处理行,把同一行中相互联通的点缩成一个 ...
- HDU - 1045 Fire Net(搜索)
Description Suppose that we have a square city with straight streets. A map of a city is a square bo ...
随机推荐
- 使用系统的某些block api(如UIView的block版本写动画时),是否也考虑循环引用问题?
系统的某些block api中,UIView的block版本写动画时不需要考虑,但也有一些api 需要考虑 以下这些使用方式不会引起循环引用的问题 [UIView animateWithDuratio ...
- git bash中文显示为数字
转自:http://blog.csdn.net/zhujiangtaotaise/article/details/74424157 今天让去做一个另外一个项目,导入项目后,git status 发现原 ...
- python使用工具简介介绍
我从研究生开学以来就开始在学python,现在来简单分享下一些基本的使用命令和快捷方式 Pycharm: 运行程序 ctrl+alt+F10 删除一行ctrl+D 注释ctrl+/ 安装python所 ...
- npm理解
NPM就是一个下载器,通过它可以下载到几乎所有你需要的代码资源.它的成功,包括如下几个方面: 海量资源:NPM背后有数以万计的开源免费模块. 高效利用:作为开发者,只需要敲几个简单的命令就可以将这些开 ...
- ubuntu添加新用户并添加管理员权限
Ubuntu创建新用户并增加管理员权限 Family 2014-06-24 22:21:22 $是普通管员,#是系统管理员,在Ubuntu下,root用户默认是没有密码的,因此也就无法使用(据说是为 ...
- 在Ignite中使用k-最近邻(k-NN)分类算法
在本系列前面的文章中,简单介绍了一下Ignite的线性回归算法,下面会尝试另一个机器学习算法,即k-最近邻(k-NN)分类.该算法基于对象k个最近邻中最常见的类来对对象进行分类,可用于确定类成员的关系 ...
- [poj] 3907 Build Your Home || 求多边形面积
原题 多组数据,到0为止. 每次给出按顺序的n个点(可能逆时针,可能顺时针),求多边形面积(保留整数) 多边形面积为依次每条边(向量)叉积/2的和 \(S=\sum _{i=1}^{n-1}p[i]* ...
- Dom的深度优先遍历和广度优先遍历
//深度优先遍历的递归写法 function DFTraversal(node) { var nodes = []; if (node != null) { nodes.push(node); var ...
- 圆盘自动机 cell
圆盘自动机 cell 一个n-m圆盘自动机,包含n个排列成一圈的方格,它们按1至n编号.每个方格中有一个整数,范围[0,m-1] .圆盘会进行d操作,每次d操作会使得每个方格中的数同时变换,变换为与其 ...
- WinDirStat is a disk usage statistics viewer
WinDirStat is a disk usage statistics viewer and cleanup tool for various versions of Microsoft Wind ...