• U68862 奶牛滑迷宫


    U68862 奶牛滑迷宫

    题目描述

    Farmer John的奶牛Besty进入了一个n*m的迷宫。

    本题的特殊之处在于,Besty只能滑着走。具体来说就是,选定一个方向后,Besty会一直向该方向滑,直到撞到墙。

    会给出Besty的起始位置。只需要滑出去即可。

    求最小的撞墙次数。

    输入格式

    第一行两个整数n,m表示迷宫大小。

    下面n行,每行m个整数,0表示空地,1表示墙。

    最后一行两个整数sx,sy表示Besty初始位置。

    输出格式

    走出迷宫的最小撞墙次数。无解请输出-1。

    输入输出样例

    输入 #1

    5 6
    1 1 1 1 1 0
    1 0 1 0 0 0
    1 0 0 1 0 1
    1 0 0 0 0 1
    1 1 0 0 1 1
    2 2
    

    输出 #1

    3
    

    输入 #2

    5 3
    1 1 1
    1 0 1
    0 0 1
    1 0 1
    1 1 1
    2 2
    

    输出 #2

    -1
    

    说明/提示

    共16个测试点。其中前13个保证1≤n,m≤30。最后3个保证1≤n,m≤100

    题解

    如果是一般的迷宫最短路, 标准解法都是BFS, 但是相比BFS, 显然DFS更容易实现, 所以在数据不大的时候, 一般会选择DFS解这类题. 但是考虑到这个题的特殊性, 一个点的最少步数可能被任何同一行或同一列的点更新, 而不是像一般的迷宫一样只能被相邻的点更新, 所以就导致了这个题用DFS不能(或很难, 没有证明的时候不能说的太绝对, 但是毕竟没有人成功过)做出.

    只要使用BFS就能轻松过.

    代码:

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<vector>
    #include<cstdio>
    #include<cmath>
    #include<queue>
    #include<map> 
    using namespace std;
    int n,m,f[1005][1005],sx,sy,qx[10005],qy[10005],fx[5]={0,1,0,-1,0},fy[5]{0,0,1,0,-1};
    bool a[1005][1005],flg=0;
    char ch;
    string s;
    void bfs(int x,int y){
    	int l=1;
    	int r=1;
    	f[x][y]=0;
    	qx[r]=x;
    	qy[r]=y;
    	while(l<=r){
    		x=qx[l];
    		y=qy[l];
    		l++;//起点出队
    		for(int i=1;i<=4;i++){//四个方向
    			int nx=x,ny=y;
    			while(!(a[nx+fx[i]][ny+fy[i]])){//不碰壁就一直走下去
    				nx+=fx[i];
    				ny+=fy[i];
    				if((nx<=0)||(nx>n)||(ny<=0)||(ny>m)){//这里不判断会RE
    					cout<<f[x][y]<<endl;//出界就是走出迷宫的答案, 只要输出来时的节点就可, 因为出迷宫不会碰壁, 下同
    					flg=1;
    					return;
    				}
    			}
    			if((nx<=0)||(nx>n)||(ny<=0)||(ny>m)){//同样是判断边界
    				cout<<f[x][y]<<endl;
    				flg=1;
    				return;
    			}
    			if((!(f[nx][ny]))&&(!((nx==sx)&&(ny==sy)))){
    				f[nx][ny]=f[x][y]+1;//从上层节点来的, 碰壁后停下, 所以比上层多碰一次
    				r++;
    				qx[r]=nx;
    				qy[r]=ny;//入队
    			}
    		}
    	}
    	return;
    }
    int main(){
    	cin>>n>>m;
    	for(int i=1;i<=n;i++){
    		for(int j=1;j<=m;j++){
    			cin>>a[i][j];
    		}
    	}
    	cin>>sx>>sy;
    	bfs(sx,sy);
    	if(!flg){//搜完之后没有出界的路径
    		cout<<-1<<endl;
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    git常用命令
    Expected Conditions的常用函数
    Docker(二十)-Docker容器CPU、memory资源限制
    Docker(十九)-Docker监控容器资源的占用情况
    ubuntu制作本地源
    ubuntu下安装软件的三种方法
    把windows的bat用好了,也很不错
    escape()、encodeURI()、encodeURIComponent()区别详解
    如何解决Ajax跨域问题-1
    五种开源协议的比较(BSD,Apache,GPL,LGPL,MIT) – 整理
  • 原文地址:https://www.cnblogs.com/Wild-Donkey/p/13057692.html
Copyright © 2020-2023  润新知