【传送门】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. NoSQL 之 Morphia 操作 MongoDB

    上两篇文章:http://www.cnblogs.com/hoojo/archive/2011/06/01/2066426.html http://www.cnblogs.com/hoojo/arch ...

  2. CF-1027-B. Curiosity Has No Limits

    CF-1027-B. Curiosity Has No Limits http://codeforces.com/contest/1072/problem/B 题意: 给定两组序列a,b,长度为n-1 ...

  3. luogu2312 解方程 (数论,hash)

    luogu2312 解方程 (数论,hash) 第一次外出学习讲过的题目,然后被讲课人的一番话惊呆了. 这个题,我想着当年全国只有十几个满分.....然后他又说了句我考场A这道题时,用了5个模数 确实 ...

  4. simulation clock gen unit (推荐)

    //Normal Clock Block always begin:clk_blk clk <=; # clk<=; #; end //Improved Clock Block, impr ...

  5. python--MySQL多表查询

    一 介绍 我们在写项目的时候一般都会建一个数据库,数据库里面会存很多的表,不可能把所有的数据都放在一张表里,因为分表来存数据节省空间,数据的组织结构更清晰,解耦和程度更高,但是这些表本质上还不是一个整 ...

  6. django第七天(模板的复用性,include标签和母版)

    django第7天模板 include标签 模板的共用 a 模板需要到使用到 登陆界面 b 模板需要使用到 登陆界面 可以把登陆界面提取到公共的模板c 为什么要用: 都需要使用相同的界面,减少代码冗余 ...

  7. BIOM Table-codes

    import numpy from biom.table import Table ========================================================== ...

  8. 经典:区间dp-合并石子

    题目链接 :http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=737 这个动态规划的思是,要得出合并n堆石子的最优答案可以从小到大枚举所有石子合并 ...

  9. log4net.dll配置以及在项目中应用

    1,首先在项目中引用log4net.dll,然后项目中添加一个配置文件log4net.config <?xml version="1.0" encoding="ut ...

  10. Python第三方库之openpyxl(11)

    Python第三方库之openpyxl(11) Stock Charts(股票图) 在工作表上按特定顺序排列的列或行中的数据可以在股票图表中绘制.正如其名称所暗示的,股票图表通常被用来说明股价的波动. ...