您的位置:首页 > 其它

hdu 1175 连连看(BFS的搜索方向与效率问题)

2015-08-07 19:59 218 查看
题目链接,点我点我!

之所以写这篇解题报告,主要是讨论一下BFS的优先搜索方向与效率问题,从Time Limits(超过10000ms)到100ms,如此大的一个跨度,深深感到自己之前写的程序有多渣,所以记录下来作为经验积累。

下面请看代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <climits>
using namespace std;
#define maxn 1005
int map[maxn][maxn];
bool vis[maxn][maxn][4];//因为数字不大,开三维数组记录方向,否则代码会很冗杂
int dx[4] = { 0,-1,0,1 };//方向向量,具体根据题目数据判断
int dy[4] = { 1,0,-1,0 };//大家可以改变搜索顺序感受一下运行时间差
int n, m;
int k, sx, sy, ex, ey;//这里尽可能不用y1.用y1在VS2012会报错,重定义,但是oj上能过,很奇怪
int flag;//做标记

struct node {
int x, y;
int dir;//方向
int turn;//记录转弯次数
};

bool judge(int x, int y) {//判断约束条件
if (x < 1 || x > n || y < 1 || y > m)
return false;
return true;
}

queue<node>q;
void bfs() {
while (!q.empty())//清空队列
q.pop();
memset(vis, 0, sizeof(vis));
node s, e;
s.x = sx;
s.y = sy;
s.dir = -1;
s.turn = 0;
q.push(s);
while (!q.empty()) {
s = q.front();
q.pop();
if (s.turn > 2)//先判断题目中约束条件
continue;
if (s.x == ex&&s.y == ey) {//目标条件
flag = 1;
printf("YES\n");
break;
}
for (int i = 0; i < 4; i++) {//这个循环看不懂的去画图
e.x = s.x + dx[i];
e.y = s.y + dy[i];
if (!judge(e.x, e.y)||vis[s.x][s.y][i])//如果把s换成e,就是Time limits!
continue;
if (map[e.x][e.y] == 0 || (e.x==ex&&e.y==ey)) {
if (s.dir == -1 || s.dir == i) {
e.dir = i;
e.turn = s.turn;
q.push(e);
vis[s.x][s.y][i] = 1;
}
else {
e.dir = i;
e.turn = s.turn + 1;
q.push(e);
vis[s.x][s.y][i] = 1;
}
}
}
}
}

int main() {
while (~scanf("%d%d", &n, &m)){
if (n == 0 && m == 0)
break;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
scanf("%d", &map[i][j]);
scanf("%d", &k);
while (k--) {
scanf("%d%d%d%d", &sx, &sy, &ex, &ey);
flag = 0;
if(map[sx][sy]==map[ex][ey]&&map[sx][sy]!=0)//还是判断约束条件
bfs();
if (!flag)
printf("NO\n");
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: