• 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;
    }
    
  • 相关阅读:
    LinkedList源码浅析
    ArrayList/Vector/Stack底层分析
    遮罩层
    重写alert方法,去掉地址显示
    继承属性的函数
    为什么手机网页点击输入框的瞬间会出现灰色背景呢?怎么去掉灰色背景?
    伪类before和after
    五星好评
    String[]字符串数组,按字典顺序排列大小
    jquery ajax的load()方法和load()事件
  • 原文地址:https://www.cnblogs.com/sdfzsyq/p/9790736.html
Copyright © 2020-2023  润新知