B17 双端队列BFS Switch the Lamp On

视频链接:118 Switch the Lamp On 双端队列BFS_哔哩哔哩_bilibili

Luogu P4667 [BalticOI 2011 Day1]Switch the Lamp On

 

 

 

 

#include <cstring>
#include <iostream>
#include <algorithm>
#include <deque>
using namespace std;

typedef pair<int,int> PII;
const int N=510;
int n,m;
char g[N][N];   //存储格内斜边
int dis[N][N];  //存储操作步数
bool vis[N][N]; //判重
char es[]="\\/\\/"; //格内斜边,左上角开始顺时针记录 
int dx[]={-1,-1,1,1},dy[]={-1,1,1,-1}; //格点增量
int ex[]={-1,-1,0,0},ey[]={-1,0,0,-1}; //格子增量

int bfs(){
  memset(dis,0x3f,sizeof dis); dis[0][0]=0;
  deque<PII> q; q.push_back({0,0});
  while(q.size()){
    PII u=q.front(); q.pop_front(); //队头出队
    int x=u.first,y=u.second; //父格点
    if(vis[x][y]) continue;   //已出过队,已最小
    vis[x][y]=true;           //出队标记,只扩展一次   
    for(int i=0; i<4; i++){
      int a=x+dx[i],b=y+dy[i];   //子格点
      if(a<0||a>n||b<0||b>m) continue;
      int ea=x+ex[i],eb=y+ey[i]; //格子
      int d=dis[x][y]+(g[ea][eb]!=es[i]);
      if(d<dis[a][b]){  //从(x,y)到(a,b)操作更少
        dis[a][b]=d;
        if(g[ea][eb]!=es[i])q.push_back({a,b});//队尾入队
        else q.push_front({a,b}); //队头入队
      }
    }
  }
  return dis[n][m];
}
int main(){
  scanf("%d%d",&n,&m);
  for(int i=0; i<n; i++) scanf("%s",g[i]);
  int d=bfs();
  if(d==0x3f3f3f3f) puts("NO SOLUTION");
  else printf("%d\n",d);
}

 

posted @ 2023-06-04 17:57  董晓  阅读(474)  评论(0编辑  收藏  举报