【传送门】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. ios 自定义RadioButton

    1 前言 众所周知在IOS中没有单选按钮这一控件,今天我们来学习一下简单的单选控件.类似与Web中的radio表单元素. 2 详述 本控件单纯的利用按钮控件和NSObject的respondsToSe ...

  2. Swift 中 String 与 CChar 数组的转换

    在现阶段Swift的编码中,我们还是有很多场景需要调用一些C函数.在Swift与C的混编中,经常遇到的一个问题就是需要在两者中互相转换字符串.在C语言中,字符串通常是用一个char数组来表示,在Swi ...

  3. 51nod——1174 区间中最大的数(ST)

    题目链接 给出一个有N个数的序列,编号0 - N - 1.进行Q次查询,查询编号i至j的所有数中,最大的数是多少. 例如: 1 7 6 3 1.i = 1, j = 3,对应的数为7 6 3,最大的数 ...

  4. cocos2d-x游戏开发(二)之创建第一个项目

    配置好开发环境之后,尝试创建一个cocos项目 (1)打开cocos2d-x安装目录,如D:\DIY\cocos2d-x-3.3 看到目录下有可执行文件 download-deps 以及 setup ...

  5. Java实现——Socket网络通信的机制以及实现举例

    1. 网络间的进程通信与Socket TCP/IP协议族中网络层的IP地址可以唯一标识网络中的主机,而传输层的协议+端口可以唯一标识主机中的应用程序(进程).这样利用这三元组就可以标识网络的进程了,网 ...

  6. 3,bool值之间的转换,和str的各个功能属性。

    bool值之间的转换 and 空字符串即为False   字符串内有内容即为True. a = 11 c = str(a) #int转换成str print(type(c)) a = ' b = in ...

  7. joyoi1935 「Poetize3」导弹防御塔

    #include <iostream> #include <cstring> #include <cstdio> #include <queue> #i ...

  8. android 之 service

    在Activity中设置两个按钮,分别为启动和关闭Service: bt01.setOnClickListener(new Button.OnClickListener() { @Override   ...

  9. Core Animation 动画

    Core Animation框架 Core Animation可以作用与动画视图或者其他可视元素,为你完成了动画所需的大部分绘帧工作.你只需要配置少量的动画参数(如开始点的位置和结束点的位置)即可使用 ...

  10. python 多线程、多进程、协程性能对比(以爬虫为例)

    基本配置:阿里云服务器低配,单核2G内存 首先是看协程的效果: import requests import lxml.html as HTML import sys import time impo ...