P1605 迷宫

题目描述

给定一个 N×MN×M 方格的迷宫,迷宫里有 TT 处障碍,障碍处不可通过。

在迷宫中移动有上下左右四种方式,每次只能移动一个方格。数据保证起点上没有障碍。

给定起点坐标和终点坐标,每个方格最多经过一次,问有多少种从起点坐标到终点坐标的方案。

输入格式

第一行为三个正整数 N,M,TN,M,T,分别表示迷宫的长宽和障碍总数。

第二行为四个正整数 SX,SY,FX,FYSX,SY,FX,FY,SX,SYSX,SY 代表起点坐标,FX,FYFX,FY 代表终点坐标。

接下来 TT 行,每行两个正整数,表示障碍点的坐标。

输出格式

输出从起点坐标到终点坐标的方案总数。

输入输出样例

输入 #1

2 2 1
1 1 2 2
1 2

输出 #1

1

说明/提示

对于 100%100% 的数据,1≤N,M≤51≤N,M≤5,1≤T≤101≤T≤10,1≤SX,FX≤n1≤SX,FX≤n,1≤SY,FY≤m1≤SY,FY≤m。

此题思路

这题其实有几种解法,一个深搜(dfs - Depth First Search),一个广搜(bfs-Breadth First Search)那我们先讲一讲深搜吧

深搜

深搜其实就是递归题目不是说了吗,起点是(1,1),重点为(n,m)那我们就把起始值设为dfs(1,1)然后每次都判断是不是为(n,m)然后遍历4个方向上下左右,我们就定义一个dx和dy来存储

int dx[4]={-1,0,1,0};

int dy[4]={0,-1,0,1};

这就是几个方向,然后在循环里定义一个X和Y为下一个方向的位置然后判断一下X和Y有没有越界如果没有在判断一下a[X][Y]是不是可走的路。如果是则继续递归下去dfs(X,Y)。

void dfs(int x,int y)
{
    if(x==n&&y==m)
	{
        p=true;
        return;
    }
    a[x][y]=1;
    for(int i=0;i<4;i++)
	{
        int X=x+dx[i];
        int Y=y+dy[i];
        if(X>0&&X<=n&&Y>0&&Y<=m)
        {
        	if(a[X][Y]==0) 
        	{
        		dfs(X,Y);
			}
		}
    }
}

这就是dfs里面的代码,完整的就是:

#include<bits/stdc++.h>
using namespace std;
int n,m,a[110][110];
bool p;
int dx[4]={-1,0,1,0};
int dy[4]={0,-1,0,1};
void dfs(int x,int y)
{
    if(x==n&&y==m)
	{
        p=true;
        return;
    }
    a[x][y]=1;
    for(int i=0;i<4;i++)
	{
        int X=x+dx[i];
        int Y=y+dy[i];
        if(X>0&&X<=n&&Y>0&&Y<=m)
        {
        	if(a[X][Y]==0) 
        	{
        		dfs(X,Y);
			}
		}
    }
}
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
    	for(int j=1;j<=m;j++)
		{
			char x;
            cin>>x;
            if(x=='#') 
            {
            	a[i][j]=1;
			}
        }
	}
    if(a[1][1]==1||a[n][m]==1)
	{
		cout<<"No";
		return 0;
	}
    dfs(1,1);
    if(p) 
    {
    	cout<<"Yes";
	}
	else 
	{
		cout<<"No";
	}
	return 0;
}

学会了吗?

广搜

广搜其实就是定义一个queue的队列,然后定义一个结构体

struct node
{
    int x;//此时的横坐标
    int y;//此时的竖坐标
};

然后将那个队列q给定义成node类型(有点不想写了......)

然后呢在bfs中定义一个node类型的w为起始点w.x=1,w.y=1

然后呢将w入队,接下来一个while循环直到q队列为空,那就代表没法到达输出"No"

在while循环中w=q.front()为头一个然后去除为元素,然后看一下w是不是为终点,如果是则输出"Yes",如果不是则和dfs一样遍历四个方向(上下左右)然后定义一个k为王此方向后的位置

node k={w.x+dx[i],w.y+dy[i]};

然后和dfs一样判断边界是否超了在判断可走并且没有标记过则标记一下为1然后入队

void bfs()
{
	node w={1,1};
	vis[1][1]=1;
	q.push(w);
	while(!q.empty())
	{
		w=q.front();
		q.pop();
		if(w.x==n1&&w.y==m1)
		{
			cout<<"Yes";
			return;
		}
		for(int i=1;i<=4;i++)
		{
			node k={w.x+dx[i],w.y+dy[i]};
			if(k.x>=1&&k.y>=1&&k.x<=n1&&k.y<=m1&&a[k.x][k.y]=='.'&&vis[k.x][k.y]==0)
			{
				vis[k.x][k.y]=1;
				q.push(k);
			}
		}
	}
	cout<<"No";
	return;
}

这就是bfs里的内容,学会了吗?以下是全文!

#include<bits/stdc++.h>
using namespace std;
const int N=101;
char a[N][N];
int n1,m1,vis[N][N];
int dx[5]={0,1,0,-1,0};
int dy[5]={0,0,-1,0,1}; 
struct node
{
	int x;
	int y;
};
queue<node>q;
void bfs()
{
	node w={1,1};
	vis[1][1]=1;
	q.push(w);
	while(!q.empty())
	{
		w=q.front();
		q.pop();
		if(w.x==n1&&w.y==m1)
		{
			cout<<"Yes";
			return;
		}
		for(int i=1;i<=4;i++)
		{
			node k={w.x+dx[i],w.y+dy[i]};
			if(k.x>=1&&k.y>=1&&k.x<=n1&&k.y<=m1&&a[k.x][k.y]=='.'&&vis[k.x][k.y]==0)
			{
				vis[k.x][k.y]=1;
				q.push(k);
			}
		}
	}
	cout<<"No";
	return;
}
int main()
{
	cin>>n1>>m1;
	for(int i=1;i<=n1;i++)
	{
		for(int j=1;j<=m1;j++)
		{
			cin>>a[i][j];
		}
	}
	if(a[1][1]=='#'||a[n1][m1]=='#')
	{
		cout<<"No";
		return 0;
	}
	bfs();
	return 0;
}

真的真的不想写注释啊!完全写不动啊!

大家学会了吗?点个关注呗!(大佬勿喷!)

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值