ZOJ2018/4月月赛G题Traffic Light(广搜)

 

 

题意:首先T组数据,每组数据包括:第一行:一个n,m,然后下面有一个n行m列的01矩阵。

   最后一行输入四个数字,分别是起点的横纵坐标,终点的横纵坐标。询问从起点到终点,最少要几步,如果到不了输出-1

     题目给定要求:1、不能停在原地 2、如果当前点是0,那么只能走上下,如果当前点是1,只能走左右。3、每走一次,整个01矩阵反过来(0变成1,1变成0这样)

思路:注意到走2次就会变回原来的图,那么只需要分情况进行广搜即可,即:记录下当前点步数然后余2,就知道当前点是0还是1。然后再根据01的走动规则来入队列。

     其次就是n和m很大,可以拿vector套vector存,也可以跟我一样拿map套pair存。

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
map<pair<int,int>,int>ma;
map<pair<int,int>,int>vis;
int n,m;
struct note{
    int x,y;
    LL step;
}p,pos;
bool judge(int x,int y){
    if(vis[make_pair(x,y)] == 1 || x<0 || x>=n || y<0 || y>=m)
        return false;
    return true;
}//判断是否越界以及走过
int go[4][2]={{0,-1},{0,1},{1,0},{-1,0}};
LL bfs(int sx,int sy,int ex,int ey){
    queue<note>q;
    p.x = sx;
    p.y = sy;
    p.step = 0;
    q.push(p);
    vis[make_pair(sx,sy)] = 1;
    while(!q.empty()){
        pos = q.front();
        q.pop();
        //printf("ca %d %d %d\n",pos.x,pos.y,pos.step);
        if(pos.x == ex && pos.y == ey) return pos.step;
        int now = pos.step % 2;//是否是原来的图
        if(now == 0){
            if(ma[make_pair(pos.x,pos.y)] == 0){
                for(int i = 2 ; i < 4;i ++){
                    int dx = pos.x + go[i][0];
                    int dy = pos.y + go[i][1];
                    if(judge(dx,dy)){
                        vis[make_pair(dx,dy)] = 1;
                        p.x = dx;
                        p.y = dy;
                        p.step = pos.step + 1;
                        if(dx== ex && dy== ey)return p.step;
                        q.push(p);
                    }
                }
            }//如果当前是0
            else{
                for(int i = 0 ; i < 2;i ++){
                    int dx = pos.x + go[i][0];
                    int dy = pos.y + go[i][1];
                    if(judge(dx,dy)){
                        vis[make_pair(dx,dy)] = 1;
                        p.x = dx;
                        p.y = dy;
                        p.step = pos.step + 1;
                        if(dx== ex && dy== ey)return p.step;
                        q.push(p);
                    }
                }
            }
        }
        else if(now == 1){
            if(ma[make_pair(pos.x,pos.y)] == 1){
                for(int i = 2 ; i < 4;i ++){
                    int dx = pos.x + go[i][0];
                    int dy = pos.y + go[i][1];
                    if(judge(dx,dy)){
                        vis[make_pair(dx,dy)] = 1;
                        p.x = dx;
                        p.y = dy;
                        p.step = pos.step + 1;
                        if(dx== ex && dy== ey)return p.step;
                        q.push(p);
                    }
                }
            }//如果当前是1
            else{
                for(int i = 0 ; i < 2;i ++){
                    int dx = pos.x + go[i][0];
                    int dy = pos.y + go[i][1];
                    if(judge(dx,dy)){
                        vis[make_pair(dx,dy)] = 1;
                        p.x = dx;
                        p.y = dy;
                        p.step = pos.step + 1;
                        if(dx== ex && dy== ey) return p.step;
                        q.push(p);
                    }
                }
            }
        }
    }
    return -1*1LL;
}
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        int sx,sy,ex,ey;
        scanf("%d %d",&n,&m);
        for(int i = 0 ; i < n ; i++){
            for(int j = 0 ; j < m ; j++){
                int x;
                scanf("%d",&x);
                pair<int,int>pii = make_pair(i,j);
                ma[pii]  = x;
                vis[pii] = 0;
            }
        }
        scanf("%d %d %d %d",&sx,&sy,&ex,&ey);
        sx-=1;sy-=1;ex-=1;ey-=1;
        printf("%d\n",bfs(sx,sy,ex,ey));
    }
    return 0;
}

posted on 2018-04-07 21:36  Esquecer  阅读(305)  评论(0编辑  收藏  举报

导航