【传送门】http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=4020

【题目大意】从起点(sx, sy)出发,要到达(ex , ey)。每次从点(x,y)走的时候要看红绿灯,灯的状态为1时只能左右走,走到(x , y+1)或者 (x , y-1);灯为0的时候只能上下走,走到(x +1, y)或者 (x-1 , y)。现在问能不能从源点走到终点,如果能,输出最少需要走多少步。

注意(x,y)代表第x行第y列,不是传统意义上的坐标系。

【题解】求最短路一般用BFS,但是与一般的图不同,这里灯的状态是不断变化的,所以允许走的方向也不同。不妨记一个步数t, t % 2 == 1或者0时方向不同,需要入队的点也不同。

另外有这样一个事实,只要访问过的点,或者说之前已经入过队的点以后都不会再入队,证明如下:

若过之前经过一个点(x0, y0), 经过若干步骤以后,又回到了(x0, y0),那么经过了多少步呢?把沿途所有点相连,必然构成一个长方形或者一条来回的直线,很显然,他们的周长必然是2的倍数,也就是偶数,因此再到这一点时这个灯的状态和上一次经过时是一样的,所以没有任何意义。当然也可能发生了这样一个情况:主人公会在这个矩形中循环走动或者在这条线段来回走动,均无法到达终点。

【代码】

#include <iostream>
#include <cstring>
#include <string>
#include <queue>
#include <vector>
using namespace std; struct Node
{
//点的坐标 走过的步数
int x, y, step;
}; int dic1[] = { ,-,, };
int dic2[] = { ,,-, }; vector<vector<int> >maps;
vector<vector<bool> >vis; int sx, sy, ex, ey;
int state;
int n, m; //判断点是否能够入队
bool judge(int x, int y)
{
if (x > && x <= n && y> && y <= m && vis[x][y] == )
{
return true;
}
return false;
} //BFS求最短路
int bfs(Node s)
{
queue <Node> Q;
Q.push(s);
Node p, q;
vis[s.x][s.y] = true; while (!Q.empty())
{
p = Q.front();
Q.pop();
//如果已经到达终点就直接返回步数即可
if (p.x == ex && p.y == ey)
{
return p.step;
}
state = maps[p.x][p.y];
//看看走到这一点共走了多少步,奇数步需要反转灯的状态,偶数步相当于不用反转
if ((p.step) % == )
{
if (state == )
{
state = ;
}
else
{
state = ;
}
}
//看这一点的状态(0,1) 确定能走到那两个点,将能到达的点入队
if (state == )
{
for (int i = ; i<; i++)
{
q.x = p.x + dic1[i];
q.y = p.y + dic2[i]; if (judge(q.x, q.y) == true)
{
vis[q.x][q.y] = true;
q.step = p.step+;
Q.push(q);
}
}
}
else if (state == )
{
for (int i = ; i<; i++)
{
q.x = p.x + dic1[i];
q.y = p.y + dic2[i]; if (judge(q.x, q.y) == true)
{
vis[q.x][q.y] = true;
q.step = p.step + ;
Q.push(q);
}
}
}
}
return -;
}
int main()
{
ios::sync_with_stdio(false);
int cas;
cin >> cas;
while (cas--)
{
cin >> n >> m;
maps.clear();
vis.clear();
maps.resize(n + );
vis.resize(n + );
for (int i = ; i <= n; i++)
{
maps[i].resize(m + );
vis[i].resize(m + );
}
for (int i = ; i <= n; i++)
{
for (int j = ; j <= m; j++)
{
cin >> maps[i][j];
}
}
cin >> sx >> sy >> ex >> ey;
if (sx == ex && sy == ey)
{
cout << << endl;
continue;
}
Node t;
t.x = sx;
t.y = sy;
t.step = ;
state = maps[sx][sy]; int ans = bfs(t);
cout << ans << endl;
}
return ;
}

ZOJ - 4020 Traffic Light (BFS)的更多相关文章

  1. ZOJ - 4020 Traffic Light 【BFS】

    题目链接 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=4020 题意 给出一张地图 以及起点和终点 求是否能从起点走到终点 ...

  2. [ZOJ 4020] Traffic Light

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=4020 很简单的一个bfs题,是我想多了. 顺便学习一下C++的S ...

  3. zoj 4020 The 18th Zhejiang University Programming Contest Sponsored by TuSimple - G Traffic Light(广搜)

    题目链接:The 18th Zhejiang University Programming Contest Sponsored by TuSimple - G Traffic Light 题解: 题意 ...

  4. zoj4020 Traffic Light(bfs+状态压缩)

    题意:每个点有两种状态,0/1,0表示只能上下方向走,1表示只能左右方向走.每走一步整个图的状态改变一次(即0->1,1->0). 数据范围:n,m<=1e15 开始迷之因为数组太大 ...

  5. ZOJ - 3890 Wumpus(BFS基础题)

    Wumpus Time Limit: 2 Seconds      Memory Limit: 65536 KB One day Leon finds a very classic game call ...

  6. ZOJ 1005 Jugs(BFS)

    Jugs In the movie "Die Hard 3", Bruce Willis and Samuel L. Jackson were confronted with th ...

  7. ZOJ 1107FatMouse and Cheese(BFS)

    题目链接 分析: 一个n * n的图,每个点是一个奶酪的体积,从0,0开始每次最多可以走k步,下一步体积必须大于上一步,求最大体积和 #include <iostream> #includ ...

  8. ZOJ 3652 Maze 模拟,bfs,读题 难度:2

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4842 要注意题目中两点: 1.在踏入妖怪控制的区域那一刹那,先减行动力,然后才 ...

  9. ZOJ 3596Digit Number(BFS+DP)

    一道比较不错的BFS+DP题目 题意很简单,就是问一个刚好包含m(m<=10)个不同数字的n的最小倍数. 很明显如果直接枚举每一位是什么这样的话显然复杂度是没有上限的,所以需要找到一个状态表示方 ...

随机推荐

  1. js parse_url 引发的

    原文链接:https://www.w3.org/TR/2011/WD-html5-20110525/origin-0.html 这里只是做下记录: 5.3 Origin — HTML5 li, dd ...

  2. react native在xcode真机调试ios

    1修改URL地址:打开项目目录下的AppDelegate.m文件,修改里面的URL,把localhost改为你的电脑的IP.在Mac系统下,你可以在系统设置/网络里找到电脑的IP地址. 2选择设备:把 ...

  3. 记服务器 httpd 服务无法启动

    httpd 服务无法重启 ,网上查到的资料都是端口号冲突 ,记录一下自己的解决办法 !!! 首先查看 服务状态 :  service status httpd / systemctl status h ...

  4. CDC相关知识点总结

    跨时钟域设计很重要,每一个项目都会有,这个要马上学会总结好.本能力属于重要而且急需的能力.

  5. 【cookie】【浏览器】各大浏览器对cookie的限制

  6. python-数字类型内置方法

    数字类型内置方法 为什么要有数据类型? 数据是用来表示状态的,不同的状态就应该用不同的数据类型去表示 整型(int) 用途:年龄.号码.银行卡号等 定义:可以使用int()方法将纯数字的字符串转换为十 ...

  7. (转)iOS开发之同一应用设置不同图标和名称

    本文转自:http://www.devzeng.com/blog/ios-two-version-app-setting-profile.html iOS开发之同一应用设置不同图标和名称 SEP 6T ...

  8. python中join()函数讲解

    本文简述的是string.join(words[, sep]),它的功能是把字符串或者列表,元组等的元素给连接起来,返回一个字符串,和split()函数与正好相反,看下面的代码理解. a=[" ...

  9. ntdsutil 清理弃用服务器-----待验证

    例子是这样的: 一个森林里有两个树,mm.com和cc.com,分别有dc www.mm.com和vdc.cc.com, cc.com域的控制器崩溃,不想恢复,要彻底删除这个域,由于vdc.cc.co ...

  10. Matplotlib基本图形之折线图

    Matplotlib基本图形之折线图折线图特点 折线图是用折线将各数据连起来组成的图形常用来观察数据随时间变化的趋势例如:股票价格,温度变化,等等 示例代码: import os import tim ...