1215 迷宫

又到了一星期一度的编程课,我们可爱的迷宫来了

首先要走迷宫,先看地图,所以我们需要一个数组来记录我们的迷宫地图

其次,就像键盘上的方向键,上下左右,需要一个数组去控制小X的运动方向

搜索的精髓在于,尽量不走重复的路线,就比如说你向下向上,向下向上。。。。(此处省略n),不还是在原地,所以,就要用一个数组去判定你要走的哪个位置是否以前已经走过了

最后,我们要用一个bool变量来告诉我们,遍历之后,是否还可以走的通

上定义区代码!!!!

此处省略框架

int next[4][2]={{0,-1},{0,1},{1,0},{-1,0}};//方向 
char mp[200][200];//地图 
bool f;//是否可以走 
int book[200][200];//是否被访问 
int nx,ny,edx,edy;//nx ny :起始位置 edx edy :结束位置
int n; 

主函数代码!

注意,我们可以先在最开始的时候就假定不可以实现

int k;     
cin
>>k; while(k--){ f=false;//假定不能行 cin>>n; memset(book,0,sizeof(book));//全部都可以走 for(int i=0;i<n;i++){ for(int j=0;j<n;j++){ cin>>mp[i][j];//输入地图 } } cin>>nx>>ny>>edx>>edy;//初始位置和目标位置 book[nx][ny]=1;//脚底下已经走过了,避免出现反复 dfs(nx,ny); if(f) cout<<"YES"<<endl; else cout<<"NO"<<endl; }

重点来了!!

函数区!!(细节看注释即可)

void dfs(int x ,int y){
    //到达目标位置
    if(x == edx && y == edy){
        f=true;
    } 
    //四个方向 
    for(int i=0;i<4;i++){
        //下一个点的坐标 
        int sx=x+next[i][0];
        int sy=y+next[i][1];
        //越界
        if(sx<0 || sx>n-1 || sy<0 || sy>n-1) continue;
        //判断是否没被标记并且不是墙 
        if(book[sx][sy] == 0 && mp[sx][sy]=='.'){
            book[sx][sy]=1;
            dfs(sx,sy);
        } 
    }
}

整合版,方便大家直接复制  

#include<bits/stdc++.h>
using namespace std;

int next[4][2]={{0,-1},{0,1},{1,0},{-1,0}};//方向 
char mp[200][200];//地图 
bool f;//是否可以走 
int book[200][200];//是否被访问 
int nx,ny,edx,edy;//nx ny :起始位置 edx edy :结束位置
int n; 

void dfs(int x ,int y){
    //到达目标位置
    if(x == edx && y == edy){
        f=true;
    } 
    //四个方向 
    for(int i=0;i<4;i++){
        //下一个点的坐标 
        int sx=x+next[i][0];
        int sy=y+next[i][1];
        //越界
        if(sx<0 || sx>n-1 || sy<0 || sy>n-1) continue;
        //判断是否没被标记并且不是墙 
        if(book[sx][sy] == 0 && mp[sx][sy]=='.'){
            book[sx][sy]=1;
            dfs(sx,sy);
        } 
    }
}

int main(){
    int k;
    cin>>k;
    while(k--){
        f=false;//假定不能行 
        cin>>n;
        memset(book,0,sizeof(book));//全部都可以走 
        
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                cin>>mp[i][j];//输入地图 
            }
        }
        
        cin>>nx>>ny>>edx>>edy;//初始位置和目标位置 
        book[nx][ny]=1;//脚底下已经走过了,避免出现反复 
        dfs(nx,ny); 
        
        if(f) cout<<"YES"<<endl;
        else cout<<"NO"<<endl; 
    }
    return 0;
} 

 我又回来了,today is 10月5日,来写个新方法,BFS()!!!!,具体细节看注释即可,就不想DFS()一样重点讲了

#include<bits/stdc++.h>
using namespace std;
struct node{//设立结构体,方便记录同一个点的横纵坐标 
    int x,y;
}que[10010];
int fx[4][2]={{1,0},{-1,0},{0,-1},{0,1}};//方向 
int book[105][105]={0};//是否被访问 
char mp[105][105]={0};//地图 
int f,r;//队首,队尾 
int k,n,la,lb,ha,hb;//la lb:起始位置 ha hb:终点 
bool ans;//是否可以 
void bfs(){
    f=r=1;//初始化队列 
    que[r].x=la , que[r].y=lb , mp[la][lb]='#';//队尾记录为初始位置,即将初始位置的横纵坐标放入队列之中,同时将此位置标记为已经访问过 
    while(f<=r){//当队列非空时,开始入队 
        node t;//建立一个新的结构体,将其队首的数据放入 
        t.x=que[f].x , t.y=que[f].y ;
        if(t.x==ha && t.y==hb){//判断条件:队首到达指定位置 
            ans=1;//可能 
            break;//直接跳出 
        }
        for(int i=0;i<4;i++){//四个方向依次遍历 
            int nx=t.x+fx[i][0];//下个位置的横坐标 
            int ny=t.y+fx[i][1];//下个位置的纵坐标 
            
            if(nx<0 || nx>n || ny<0 || ny>n) continue;//约束条件 
            
            if(!book[nx][ny] && mp[nx][ny]=='.'){//约束条件 
                mp[nx][ny]='#';//将当前位置标记为已访问 
                r++;//队尾++,准备入队 
                que[r].x=nx;//入队 
                que[r].y=ny;//入队,too 
            } 
        }
        f++;//队首出队 
    }
}
int main(){
    cin>>k;//数据组数 
    while(k--){
        cin>>n;
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                cin>>mp[i][j]; //输入 
            }
        }
        cin>>la>>lb>>ha>>hb;//输入初始位置与终点 
        ans=0;//开始假定为不可以 
        bfs();
        if(ans) cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
    }
    
    return 0;
}

 

posted @ 2020-09-25 21:45  ssdaeda  阅读(779)  评论(1编辑  收藏  举报