题目大意我就不讲了。
该题目的基本思路跟hdu 1728 一样。
BFS进行搜索,并且往一个方向搜到底。具体方法看代码吧,嘴挫,不会讲。= =!
WA了无数次,第一个地方是没有考虑不可走的方格,因为自己采用的整型数组原因,所以就错了。改了几次改回来了。
第二个地方是在于优先队列的使用问题,priority_queue需要重载<,注意你要得到从小到大,就return >,错在这边,检查半天检查不出来(头昏脑胀,连数据都看错了,以为对了= = )
#include<iostream>
#include <queue>
#include <cstring>
using namespace std;
int sx, sy, ex, ey;
bool vis[1005][1005];
short map[1005][1005];
int n, m;
int Div[4][2] = { -1, 0, 0, 1, 1, 0, 0, -1 };
int ss;//用来标记是否有符合的情况
struct pos
{
int x,y;
int turns;
friend bool operator <(pos a, pos b)//初学还不是十分理解的重载<来使用优先队列
{
return a.turns>b.turns;//只能一味的套模板,重载<,但里面是>号,这样使得符合的从小到大排列
}
};
bool check(int x, int y)
{
if (x > n || x <= 0 || y > m || y <= 0 || vis[x][y])//检查越界以及有没有被走过了
return false;
return true;
}
void bfs()
{
memset(vis, 0, sizeof(vis));//在使用标记数组前要清零。
priority_queue<pos>q;//优先队列的写法,再写一遍,防止忘了,priority_queue
pos p, mid;
p.x = sx;
p.y = sy;
p.turns = -1;//因为下面一开始就要+1,所以该处要赋值为-1,读者体会一下。
q.push(p);
vis[sx][sy] = 1;
while (!q.empty())
{
p = q.top();
q.pop();
if (p.x == ex&&p.y == ey)
{
if (p.turns <= 2)ss = 1;//终止条件,只要有到达终点,然后转弯处小于2的,就符合,讲ss赋值为1,跳出。
return;
}
p.turns++;//因为该处方向已经被搜索完了,所以肯定要转弯。
for (int i = 0; i < 4; i++)
{
mid.x = p.x + Div[i][0];
mid.y = p.y + Div[i][1];
mid.turns = p.turns;
while (check(mid.x, mid.y))
{
if (map[mid.x][mid.y]&&(mid.x!=ex||mid.y!=ey))//这边是要检查该点是否为0(不可走)非0是方块。方块的话就要考虑是不是终点。第一个wa就是wa在这里。
{
vis[mid.x][mid.y] = true;//讲非终点的方块标记为检查过,防止再走。
break;
}
vis[mid.x][mid.y] = true;//标记
q.push(mid);
mid.x = mid.x + Div[i][0];//往这个方向一直走,直到不符合条件。
mid.y = mid.y + Div[i][1];
}
}
}
}
int main()
{
while (cin >> n >> m&&n+m)
{
for (int i = 1; i <=n;i++)
for (int j = 1; j <=m;j++)
cin >> map[i][j];
int k;
cin >> k;
for (int i = 0; i < k; i++)
{
ss = 0;
cin >> sx >> sy >> ex >> ey;
if (map[sx][sy] != map[ex][ey] || map[sx][sy] == 0 || map[ex][ey] == 0)//稍微很明显的剪枝
{
cout << "NO" << endl;
continue;
}
bfs();
if (ss)
cout << "YES" << endl;
else
cout << "NO" << endl;
}
}
}