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(搜索剪枝)的更多相关文章

  1. HDOJ(HDU).1045 Fire Net (DFS)

    HDOJ(HDU).1045 Fire Net [从零开始DFS(7)] 点我挑战题目 从零开始DFS HDOJ.1342 Lotto [从零开始DFS(0)] - DFS思想与框架/双重DFS HD ...

  2. hdu 1045 Fire Net(最小覆盖点+构图(缩点))

    http://acm.hdu.edu.cn/showproblem.php?pid=1045 Fire Net Time Limit:1000MS     Memory Limit:32768KB   ...

  3. HDU 1045(Fire Net)题解

    以防万一,题目原文和链接均附在文末.那么先是题目分析: [一句话题意] 给定大小的棋盘中部分格子存在可以阻止互相攻击的墙,问棋盘中可以放置最多多少个可以横纵攻击炮塔. [题目分析] 这题本来在搜索专题 ...

  4. HDU 1045 Fire Net 【连通块的压缩 二分图匹配】

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1045 Fire Net Time Limit: 2000/1000 MS (Java/Others)    ...

  5. HDU 1045 Fire Net(dfs,跟8皇后问题很相似)

    传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1045 Fire Net Time Limit: 2000/1000 MS (Java/Others)   ...

  6. HDU 1045——Fire Net——————【最大匹配、构图、邻接矩阵做法】

    Fire Net Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Sta ...

  7. HDU 1045 Fire Net 状压暴力

    原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1045 Fire Net Time Limit: 2000/1000 MS (Java/Others)  ...

  8. HDU 1045 Fire Net 二分图建图

    HDU 1045 题意: 在一个n*n地图中,有许多可以挡住子弹的墙,问最多可以放几个炮台,使得炮台不会相互损害.炮台会向四面发射子弹. 思路: 把行列分开做,先处理行,把同一行中相互联通的点缩成一个 ...

  9. HDU - 1045 Fire Net(搜索)

    Description Suppose that we have a square city with straight streets. A map of a city is a square bo ...

随机推荐

  1. 剑指Offer - 九度1507 - 不用加减乘除做加法

    剑指Offer - 九度1507 - 不用加减乘除做加法2013-11-29 20:00 题目描述: 写一个函数,求两个整数之和,要求在函数体内不得使用+.-.*./四则运算符号. 输入: 输入可能包 ...

  2. 《数据结构》C++代码 BFS与DFS

    BFS,广度优先搜索,一层一层去遍历图,故称广度优先.实现方式:队列. DFS,深度优先搜索,撞墙才回头的遍历,称为深度优先.实现方式:递归(栈). 这两种遍历方式,是访问图的基本方式.如果拿树做对比 ...

  3. Python 绘制棋盘

    import turtle pen = turtle.Pen() pen.speed(10) width = 30 # 格子宽度 count = 18 # 横向纵向格子数 o = width * co ...

  4. 课时17:函数:Python的乐高积木

    目录: 一.创建和调用函数 二.函数的参数 三.函数的返回值 四.课时17课后习题及答案 为了使得程序得代码变得简单,就需要把程序分解成较小得组成部分.有三种方法可以实现:函数.对象.模块. **** ...

  5. C# MemoryCache 类[转载]

    原网址:http://www.cmono.net/post/read/156 MemoryCache 类是.Net .0推出的类库,主要是为了方便在Winform和Wpf中构建缓存框架的 Object ...

  6. HTTP 返回状态代码详细解释

    一:1xx(临时响应)表示临时响应并需要请求者继续执行操作的状态代码. 100(继续)请求者应当继续提出请求. 服务器返回此代码表示已收到请求的第一部分,正在等待其余部分:101(切换协议)请求者已要 ...

  7. 【bzoj1565】[NOI2009]植物大战僵尸 拓扑排序+最大权闭合图

    原文地址:http://www.cnblogs.com/GXZlegend/p/6808268.html 题目描述 输入 输出 仅包含一个整数,表示可以获得的最大能源收入.注意,你也可以选择不进行任何 ...

  8. hdu 2510 符号三角形 (DFS+打表)

    符号三角形 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

  9. hdu 2544 最短路 (最短路径)

    最短路 Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...

  10. Codeforces Round #389 (Div. 2) 752E(二分答案)

    题目大意 可以理解成有n个木板,可以选取木板将其劈成2半(如果长度是奇数,就切成x和x+1),切完之后还可以再切 然后你要把这n个木板切成更多的木板,然后从中选择k个,使得这k个木板的最小长度尽量大 ...