题目链接

http://acm.hdu.edu.cn/showproblem.php?pid=1175

思路

这种题一想到就用搜索, 但是内存是32m 用 bfs 会不会MLE

没错 第一次 BFS的时候 MLE了 但是加入一些剪枝 就可以过

0.先判断两个位置的棋子是否存在并且相同

1.如果转弯次数 > 2 就不用搜下去

2.如果转弯次数 == 2 那么可以判断一下 从这个点到达终点的路径上 是否还要转弯

如果不是 可以继续判断一下路径上是否存在障碍 如果是 就剪掉

如果还需要 转弯 也可以剪掉

这么剪枝 用DFS 63ms BFS 124ms

然后转弯怎么判断

首先可以发现 如果本来的方向是向上的 那么我们不需要扩展向下走那个方向 因为走了回头路

只需要扩展的是 向上 向左 向右 那么转弯次数 分别为 0 1 1

我们只需要 0 -> up 1 -> right 2 -> down 3 -> left 这样映射起来

那么我们只需要用计算 |当前走的方向-之前走的方向|

如果 为2 就 continue

如果为 3 就是 1

如果为0 或者为1 就是本值

AC代码_BFS

#pragma comment(linker, "/STACK:102400000,102400000")

#include <cstdio>
#include <cstring>
#include <ctype.h>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <map>
#include <stack>
#include <set>
#include <list>
#include <numeric>
#include <sstream>
#include <iomanip>
#include <limits> #define CLR(a, b) memset(a, (b), sizeof(a));
#define pb push_back
#define bug puts("***bug***");
#define fi first
#define se second
#define L(on) (on<<1)
#define R(on) (L(on) | 1)
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define syn_close ios::sync_with_stdio(false); cin.tie(0);
#define sp system("pause");
#define gets gets_s using namespace std; typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef long double ld;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <string, int> psi;
typedef pair <string, string> pss;
typedef pair <double, int> pdi; const double PI = acos(-1.0);
const double EI = exp(1.0);
const double eps = 1e-8; const int INF = 0x3f3f3f3f;
const ll INFLL = 0x3f3f3f3f3f3f3f3fll;
const int maxn = (int)1e3 + 10;
const int MOD = (int)1e9 + 7; int G[maxn][maxn];
int visit[maxn][maxn];
int n, m, q;
int sx, sy, ex, ey;
int ans; void input()
{
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
scanf("%d", &G[i][j]);
} struct node
{
int x, y, turn, dir;
node () {}
node (int x, int y, int turn, int dir) : x(x), y(y), turn(turn), dir(dir) {}
}; int Move[4][2] =
{
-1, 0,
0, 1,
1, 0,
0,-1,
}; bool ok(int x, int y)
{
if (x < 0 || x >= n || y < 0 || y >= m || G[x][y])
return false;
return true;
} bool judge(int x, int y, int dir) // 剪枝 如果turn == 2 并且 这个点到达终点还需要转弯,可以直接剪掉 或者在到达终点的路上存在障碍 也可以剪掉
{
if (x != ex && y != ey) return true;
if (x == ex)
{
if (dir == 1)
{
if (ey < y) return true;
else
{
for (int i = y + 1; i < ey; i++)
if (G[x][i]) return true;
}
}
if (dir == 3)
{
if (ey > y)
return true;
else
for (int i = y - 1; i > ey; i--)
if (G[x][i]) return true;
}
}
if (y == ey)
{
if (dir == 0)
{
if (ex > x) return true;
else
for (int i = x - 1; i > ex; i--)
if (G[i][y]) return true;
}
if (dir == 2 && ex < x)
{
if (ex < x) return true;
else
for (int i = x + 1; i < ex; i++)
if (G[i][y]) return true;
}
}
return false;
} void bfs()
{
queue <node> q;
for (int i = 0; i < 4; i++)
q.push(node(sx, sy, 0, i));
CLR(visit, 0x3f);
visit[sx][sy] = 0;
while (!q.empty())
{
node u = q.front(); q.pop();
if (u.turn > 2) continue;
if (u.turn == 2 && judge(u.x, u.y, u.dir)) continue;
for (int i = 0; i < 4; i++)
{
int nx = u.x + Move[i][0];
int ny = u.y + Move[i][1];
if (ok(nx, ny))
{
if (abs(i - u.dir) == 2) continue;
int turn = u.turn + (abs(i - u.dir) == 3 ? 1 : abs(i - u.dir));
if (turn < visit[nx][ny])
{
visit[nx][ny] = turn;
if (nx == ex && ny == ey && turn <= 2)
{
ans = 1;
return;
}
q.push(node(nx, ny, turn, i));
}
}
}
}
return;
} int main()
{
while (scanf("%d%d", &n, &m) && (n || m))
{
input();
cin >> q;
while (q--)
{
scanf("%d%d%d%d", &sx, &sy, &ex, &ey);
sx--, sy--, ex--, ey--;
if (G[sx][sy] && G[ex][ey] && G[sx][sy] == G[ex][ey])
{
ans = 0;
G[ex][ey] = 0;
bfs();
G[ex][ey] = G[sx][sy];
puts(ans ? "YES" : "NO");
}
else puts("NO");
}
}
}

AC代码_DFS

#pragma comment(linker, "/STACK:102400000,102400000")

#include <cstdio>
#include <cstring>
#include <ctype.h>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <map>
#include <stack>
#include <set>
#include <list>
#include <numeric>
#include <sstream>
#include <iomanip>
#include <limits> #define CLR(a, b) memset(a, (b), sizeof(a));
#define pb push_back
#define bug puts("***bug***");
#define fi first
#define se second
#define L(on) (on<<1)
#define R(on) (L(on) | 1)
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define syn_close ios::sync_with_stdio(false); cin.tie(0);
#define sp system("pause");
#define gets gets_s using namespace std; typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef long double ld;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <string, int> psi;
typedef pair <string, string> pss;
typedef pair <double, int> pdi; const double PI = acos(-1.0);
const double EI = exp(1.0);
const double eps = 1e-8; const int INF = 0x3f3f3f3f;
const ll INFLL = 0x3f3f3f3f3f3f3f3fll;
const int maxn = (int)1e3 + 10;
const int MOD = (int)1e9 + 7; int G[maxn][maxn];
int visit[maxn][maxn];
int n, m, q;
int sx, sy, ex, ey;
int ans; void input()
{
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
scanf("%d", &G[i][j]);
} struct node
{
int x, y, turn, dir;
node () {}
node (int x, int y, int turn, int dir) : x(x), y(y), turn(turn), dir(dir) {}
}; int Move[4][2] =
{
-1, 0,
0, 1,
1, 0,
0,-1,
}; bool ok(int x, int y)
{
if (x < 0 || x >= n || y < 0 || y >= m || G[x][y])
return false;
return true;
} bool judge(int x, int y, int dir) // 剪枝 如果turn == 2 并且 这个点到达终点还需要转弯,可以直接剪掉 或者存在障碍
{
if (x != ex && y != ey) return true;
if (x == ex)
{
if (dir == 1)
{
if (ey < y) return true;
else
{
for (int i = y + 1; i < ey; i++)
if (G[x][i]) return true;
}
}
if (dir == 3)
{
if (ey > y)
return true;
else
for (int i = y - 1; i > ey; i--)
if (G[x][i]) return true;
}
}
if (y == ey)
{
if (dir == 0)
{
if (ex > x) return true;
else
for (int i = x - 1; i > ex; i--)
if (G[i][y]) return true;
}
if (dir == 2 && ex < x)
{
if (ex < x) return true;
else
for (int i = x + 1; i < ex; i++)
if (G[i][y]) return true;
}
}
return false;
} void dfs(int x, int y, int turn, int dir)
{
if (turn > 2 || ans) return;
if (x == ex && y == ey)
{
ans = 1;
return;
}
if (turn == 2 && judge(x, y, dir)) return;
for (int i = 0; i < 4 && ans == 0; i++)
{
if (abs(i - dir) == 2) continue;
int tmp = abs(i - dir) == 3 ? 1 : abs(i - dir);
int nx = x + Move[i][0];
int ny = y + Move[i][1];
if (ok(nx, ny))
{
if (turn + tmp < visit[nx][ny])
{
visit[nx][ny] = turn + tmp;
dfs(nx, ny, turn + tmp, i);
}
}
}
} int main()
{
while (scanf("%d%d", &n, &m) && (n || m))
{
input();
cin >> q;
while (q--)
{
scanf("%d%d%d%d", &sx, &sy, &ex, &ey);
sx--, sy--, ex--, ey--;
if (G[sx][sy] && G[ex][ey] && G[sx][sy] == G[ex][ey])
{
ans = 0;
G[ex][ey] = 0;
CLR(visit, 0x3f);
for (int i = 0; i < 4 && ans == 0; i++)
dfs(sx, sy, 0, i);
G[ex][ey] = G[sx][sy];
puts(ans ? "YES" : "NO");
}
else puts("NO");
}
}
}

HDU - 1175 连连看 【DFS】【BFS】的更多相关文章

  1. hdu - 1728逃离迷宫 && hdu - 1175 连连看 (普通bfs)

    http://acm.hdu.edu.cn/showproblem.php?pid=1728 这两道题花了一下午的时候调试,因为以前做过类似的题,但是判断方向的方法是错的,一直没发现啊,真无语. 每个 ...

  2. hdu 1175 连连看 DFS

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1175 解题思路:从出发点开始DFS.出发点与终点中间只能通过0相连,或者直接相连,判断能否找出这样的路 ...

  3. HDU 1175 连连看(BFS)

    连连看 Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submi ...

  4. HDU 1175 连连看 (DFS+剪枝)

    <题目链接> 题目大意:在一个棋盘上给定一个起点和终点,判断这两点是否能通过连线连起来,规定这个连线不能穿过其它的棋子,并且连线转弯不能超过2次. 解题分析:就是DFS从起点开始搜索,只不 ...

  5. HDU 1175 连连看【BFS】

    题意:给出起点和终点的棋子,不能经过别的棋子,而且转弯的次数不能超过2次,问能否消除 和逃离迷宫一样,每个节点记录下来它的当前的方向和转弯的次数,再搜 注意特判起点的棋子和终点的棋子为0或者不一样的情 ...

  6. HDU 1175 连连看(超级经典的bfs之一)

    传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1175 连连看 Time Limit: 20000/10000 MS (Java/Others)     ...

  7. POJ2308连连看dfs+bfs+优化

    DFS+BFS+MAP+剪枝 题意:       就是给你一个10*10的连连看状态,然后问你最后能不能全部消没? 思路:      首先要明确这是一个搜索题目,还有就是关键的一点就是连连看这个游戏是 ...

  8. Hdu 1175 连连看(DFS)

    Problem地址:http://acm.hdu.edu.cn/showproblem.php?pid=1175 因为题目只问能不能搜到,没问最少要几个弯才能搜到,所以我采取了DFS. 因为与Hdu ...

  9. HDU 1175 连连看 (深搜+剪枝)

    题目链接 Problem Description "连连看"相信很多人都玩过.没玩过也没关系,下面我给大家介绍一下游戏规则:在一个棋盘中,放了很多的棋子.如果某两个相同的棋子,可以 ...

随机推荐

  1. 工业控制系统USB存储设备可信管理方案的(ICICS2015)论文PPT:TMSUI: A Trust Management Scheme

    本PPT是发表在ICICS2015 大会的论文 TMSUI: A Trust Management Scheme of USB Storage Devices for Industrial Contr ...

  2. UVA - 434 Matty&#39;s Blocks

    题意:给你正视和側视图,求最多多少个,最少多少个 思路:贪心的思想.求最少的时候:由于能够想象着移动,尽量让两个视图的重叠.所以我们统计每一个视图不同高度的个数.然后计算.至于的话.就是每次拿正视图的 ...

  3. 【Excle数据透视表】如何得到数据透视表中某个汇总行的明细数据

    例如: 现在想得到"北京 汇总"的明细数据,该怎么处理呢? 步骤 右键数据透视表任意单元格→数据透视表选项→启用显示明细数据→确定→单击"北京 汇总"行最后一个 ...

  4. 压力测试衡量CPU的三个指标:CPU Utilization、Load Average和Context Switch Rate

    分类: 4.软件设计/架构/测试 2010-01-12 19:58 34241人阅读 评论(4) 收藏 举报 测试loadrunnerlinux服务器firebugthread 上篇讲如何用LoadR ...

  5. 《windows核心编程》 在应用程序中使用虚拟内存

    Microsoft Windows 提供了以下三种机制来对内存进行操控: 虚拟内存 最适合用来管理大型对象数组或大型结构数组 内存映射文件 最适合用来管理大型数据流(通常是文件),以及在同一台机器上运 ...

  6. Repeater绑定List泛型对象

    后台: public void BindData()        {            List<WeiBo> DataList = new List<WeiBo>(); ...

  7. Delphi中定义了四种布尔类型:Boolean,ByteBool,WordBool和LongBool。后面三种布尔类型是为了与其他语言兼容而引入的

    bool是LongBool类型. Delphi中定义了四种布尔类型:Boolean,ByteBool,WordBool和LongBool.后面三种布尔类型是为了与其他语言兼容而引入的,一般情况下建议使 ...

  8. poj 3537 Crosses and Crosses 博弈论之grundy值

    题意: 给1*n的格子,轮流在上面叉叉,最先画得3个连续叉叉的赢.问先手必胜还是必败. 分析: 求状态的grundy值(也就是sg值),详细怎么求详见代码.为什么这么求要自己想的,仅仅可意会(别人都说 ...

  9. C++ Primer(第五版)读书笔记 & 习题解答 --- Chapter 1

    Chapter 1.1 1. 每个C++程序都必须有且只能有一个main函数,main函数的返回类型必须是int.操作系统通过调用main函数来运行C++程序. 2. 一个函数的定义包含四部分:返回类 ...

  10. HTML_<a>

    1.在a标签中调用js函数最适当的方法推荐使用: (1) a href="javascript:void(0);" onclick="js_method()" ...