【传送门】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. 一款App的开发成本是多少?

    答一: 接触过上万名创业者,开发上线过超过30款App,没有比我更适合回答这个问题的了.. 本文对想做好一款App项目的人来说这是一篇价值百万的回答!因为这是我们花了几百万试错成本试出来的经验! &l ...

  2. objdump命令

    0x00 objdump命令是Linux下的反汇编目标文件或者可执行文件的命令 0x01 objdump -f   显示test的文件头信息 $ objdump -f levellevel: file ...

  3. 基于IMD的包过滤防火墙原理与实现

    一.前言二.IMD中间层技术介绍三.passthru例程分析四.部分演示代码五.驱动编译与安装六. 总结 一.前言 前段时间,在安全焦点上看到了TOo2y朋友写的<基于SPI的数据报过滤原理与实 ...

  4. Mac OSX用 dd 命令,浇灌ISO镜像到USB驱动器

    Mac OSX用 dd 命令,浇灌ISO镜像到USB驱动器 字数244 阅读197 评论0 喜欢0 把ISO镜像转换为一个可启动的USB设备.一种可行的方法是通过OS X的Terminal “浇灌”到 ...

  5. PHP 线上项目 无法操作

    部署到线上的项目,http 环境没有问题,首页展示没有问题,但是跳转页面展示到了本地, 解决办法 : 更改文件夹所属用户 chown -R apache:apache html

  6. Python基础:字典(dict)与集合(set)

    查找场景下与列表的性能对比 字典与集合之所以高效的原因是:内部结构都是一张哈希表. 平均情况下插入.查找和删除的时间复杂度为 O(1). 假设有数量100,000的产品列表: import time ...

  7. Django 千锋培训的学习笔记(1)

    Django 千锋培训读书笔记 https://www.bilibili.com/video/av17879644/?p=1 切换到创建项目的目录 cd C:\Users\admin\Desktop\ ...

  8. map函数的应用:UVa156-Ananagrams

    Ananagrams Most crossword puzzle fans are used to anagrams - groups of words with the same letters i ...

  9. 【18】什么是FOUC?如何避免

    [18]什么是FOUC?如何避免 Flash Of Unstyled Content: 用户定义样式表加载之前浏览器使用默认样式显示文档,用户样式加载渲染之后再从新显示文档,造成页面闪烁. 解决方法: ...

  10. python-通过openpy操作excel

    1.安装 openpyxl pip install openpyxl == 2.3.5  安装指定版本 遇到问题: 查询结果:这是因为电脑上有其他软件也有pip命令,我的电脑上是因为装了loadrun ...