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

本文介绍了一种使用广度优先搜索(BFS)解决特定交通灯状态下的最短路径问题的方法。通过定义节点状态和步骤数,实现了一个能够根据交通灯的不同状态找到从起点到终点最短路径的算法。

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

题解:

题意自己翻译,此题首先肯定是要广搜的,不过要开一个1e5*1e5的数组好像有点困难,

所以用结构体来存每个点的下标,然后从源点开始广搜。定义一个pair<node,int>,第一个存节点信息,第二个存到当前节点的步数,因为还要处理到达每个节点的状态。

状态:走奇数步并且状态为1与走偶数步状态为0的结果是一样的,都是向左或向右移动。走偶数步并且状态为1与走奇数步状态为0的结果也是一样,可以向上或向下移动。

最后定义一个pair的队列。

代码:

#include <stdio.h>
#include <iostream>
#include <vector>
#include <queue>
#include <string.h>
#include <utility>
#define IO ios::sync_with_stdio(0);\
    cin.tie(0);cout.tie(0);
using namespace std;
const int N = 1e5+5;
struct node
{
    int i,j,value;
    int flag;
} res[N];
pair <node,int> p;
queue <pair<node,int > > q;
int main()
{
    int T;
    cin >> T;
    while(T--)
    {
        memset(res,0,sizeof(res));
        int m,n,x,num = 0;
        cin >> n >> m;
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= m; j++)
                cin >> x,res[++num].value = x,res[num].i = i,res[num].j=j;
        int x1,y1,x2,y2;
        cin >>x1>>y1>>x2>>y2;
        int sum = 0;
        res[(x1-1)*m + y1].flag = 1;
        p.first = res[(x1-1)*m + y1];
        p.second = sum;
        q.push(p);
        int ans = 0,ff = 0;
        while(!q.empty())
        {
            pair <node,int> pp;
            pp = q.front();
            q.pop();
            int i = pp.first.i,j = pp.first.j,value = pp.first.value,sum = pp.second;
            if(i==x2&&j==y2)
            {
                ans = sum;
                ff = 1;
                break;
            }
            if(((sum&1)&&value==1)||(!(sum&1)&&value==0))
            {
                if(i+1<=n&&res[i*m+j].flag==0)
                {
                    pp.first.i = i+1,pp.first.j = j,pp.first.value = res[(i)*m+j].value;
                    pp.first.flag = 1;
                    res[(i)*m+j].flag = 1;
                    pp.second = sum+1;
                    q.push(pp);
                }
                if(i-1>0&&res[(i-2)*m+j].flag==0)
                {
                    pp.first.i = i-1,pp.first.j = j,pp.first.value = res[(i-2)*m+j].value;
                    pp.first.flag = 1;
                    res[(i-2)*m+j].flag = 1;
                    pp.second = sum+1;
                    q.push(pp);
                }
            }
            else
            {
                if(j+1<=m&&res[(i-1)*m+j+1].flag==0)
                {
                    pp.first.i = i,pp.first.j = j+1,pp.first.value = res[(i-1)*m+j+1].value;
                    pp.first.flag = 1;
                    res[(i-1)*m+j+1].flag = 1;
                    pp.second = sum+1;
                    q.push(pp);
                }
                if(j-1>0&&res[(i-1)*m+j-1].flag==0)
                {
                    pp.first.i = i,pp.first.j = j-1,pp.first.value = res[(i-1)*m+j-1].value;
                    pp.first.flag = 1;
                    res[(i-1)*m+j-1].flag = 1;
                    pp.second = sum+1;
                    q.push(pp);
                }
            }
        }
        printf("%d\n",ff?ans:-1);
        while(!q.empty())q.pop();
    }
    return 0;
}
/*
4
2 3
1 1 0
0 1 0
1 3 2 1
2 3
1 0 0
1 1 0
1 3 1 2
2 2
1 0
1 0
1 1 2 2
1 2
0 1
1 1 1 1
*/

 

转载于:https://www.cnblogs.com/GHzz/p/8734231.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值