B17 双端队列BFS Switch the Lamp On

视频链接:B17 双端队列BFS Switch the Lamp On_哔哩哔哩_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 e[N][N]; //格内斜边
int d[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}; //格子增量
deque<PII> q; //双端队列

int bfs(){
  memset(d,0x3f,sizeof d); d[0][0]=0;
  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]=1; 
    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 dd=d[x][y]+(e[ea][eb]!=es[i]);
      if(dd<d[a][b]){ //入队优化
        d[a][b]=dd;
        if(e[ea][eb]!=es[i])q.push_back({a,b});
        else q.push_front({a,b});
      }
    }
  }
  return d[n][m];
}
int main(){
  scanf("%d%d",&n,&m);
  for(int i=0; i<n; i++) scanf("%s",e[i]);
  int dd=bfs();
  if(dd==0x3f3f3f3f) puts("NO SOLUTION");
  else printf("%d\n",dd);
}

 

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