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; }