CF 1063B Labyrinth

传送门

解题思路

看上去很简单,(bfs)写了一发被(fst)。。。后来才知道好像一群人都被(fst)了,这道题好像那些每个点只经过一次的传统(bfs)都能被叉,只需要构造出一个一块一直上下走,还有一块一直左右走,上下走走到左右走的格子里更优,但已经更新不了,就(GG)了。后来学习了一下(rank1)的代码,其实用一个双端队列就可以避免这个问题,每次把上下走的放到队头,左右走的放到队尾。这样的话每次左右遍历时一定是最优的。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>

using namespace std;
const int MAXN = 2005;

int n,m,stx,sty,X,Y,ans;
bool vis[MAXN][MAXN];
char mp[MAXN][MAXN];
deque<int> Q[5];

void bfs(){
	Q[1].push_front(stx),Q[2].push_front(sty),Q[3].push_front(X),Q[4].push_front(Y);
	while(Q[1].size()){
		int x=Q[1].front(),y=Q[2].front(),l=Q[3].front(),r=Q[4].front();
		Q[1].pop_front();Q[2].pop_front();Q[3].pop_front();Q[4].pop_front();
		if(vis[x][y]) continue;vis[x][y]=1;ans++;
		if(x-1>=1 && mp[x-1][y]!='*')  {
			Q[1].push_front(x-1);Q[2].push_front(y);Q[3].push_front(l);Q[4].push_front(r);			
		}
		if(x+1<=n && mp[x+1][y]!='*'){
			Q[1].push_front(x+1);Q[2].push_front(y);Q[3].push_front(l);Q[4].push_front(r);
		}
		if(y-1>=1 && mp[x][y-1]!='*' && l) {
			Q[1].push_back(x);Q[2].push_back(y-1);Q[3].push_back(l-1);Q[4].push_back(r);
		}
		if(y+1<=m && mp[x][y+1]!='*' && r){
			Q[1].push_back(x);Q[2].push_back(y+1);Q[3].push_back(l);Q[4].push_back(r-1);
		}
	}
}

int main(){
	scanf("%d%d%d%d%d%d",&n,&m,&stx,&sty,&X,&Y);
	for(int i=1;i<=n;i++) scanf("%s",mp[i]+1);
	bfs();cout<<ans;
	return 0;
}
原文地址:https://www.cnblogs.com/sdfzsyq/p/9790736.html