预备队第四周题解

预备队第四周题解

迷宫

题目描述

给定一个 NXM 方格的迷宫,迷宫里有 T 处障碍,障碍处不可通过。

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

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

输入格式

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

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

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

输出格式

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

样例 #1

样例输入 #1

2 2 1
1 1 2 2
1 2

样例输出 #1

1

思路

使用深度优先搜索,输入起始位置和最终位置,移动方向有四种,每次先判断是否为终点,不是则移动,并标记已经走过,判断移动后的点是否不符合条件,符合则继续走,不符合就换另一种走法,这个点的所有走法结束后将该点的vis恢复成0.

代码

#include<iostream>
using namespace std;
int n, m, t;
int num;
int vis[100][100];
int arrx[4] = { -1,1,0,0 };
int arry[4] = { 0,0,-1,1 };
void dfs(int sx,int sy,int fx,int fy)
{
	if (sx == fx && sy == fy)
	{
		num++;
		return;
	}
	else
	{
		vis[sx-1][sy-1] = 1;
		for (int i = 0;i <= 3;i++)
		{
			int tsx = sx + arrx[i];
			int tsy = sy + arry[i];
			if (tsx > 0 && tsx <= n && tsy > 0 && tsy <= m && !vis[tsx-1][tsy-1])
			{

				dfs(tsx,tsy, fx, fy);
			}
		}
		vis[sx - 1][sy - 1] = 0;
	}
}
int main()
{
	cin >> n >> m >> t;
	int sx, sy, fx, fy;
	cin >> sx >> sy >> fx >> fy;
	for (int i = 0;i < t;i++)
	{
		int x, y;
		cin >> x>> y;
		vis[x-1][y-1] = 1;
	}
	dfs(sx, sy, fx, fy);
	cout << num;
	return 0;
}

马的遍历

题目描述

有一个 nXm的棋盘,在某个点 (x, y) 上有一个马,要求你计算出马到达棋盘上任意一个点最少要走几步。

输入格式

输入只有一行四个整数,分别为 n, m, x, y。

输出格式

一个 nXm的矩阵,代表马到达某个点最少要走几步(不能到达则输出 -1)。

样例 #1

样例输入 #1

3 3 1 1

样例输出 #1

0    3    2    
3    -1   1    
2    1    4

思路

利用广度优先搜索,输入范围大小,和起始位置,创建一个结构体,元素为坐标,将起始点存入队列,并将其坐标对应步数标记为1,然后将队列头元素取出,并依次将8种走法存入队列,并对移动后的位置进行判断,以此类推直到队列中没有元素。

代码

#include<iostream>
#include<queue>
using namespace std;
struct local
{
	int lx;
	int ly;
	local(int x, int y)
	{
		lx = x;
		ly = y;
	}
};
queue <local> q;
int n, m, x, y;
int arrx[8] = { -1,-2,-2,-1,1,2,2,1 };
int arry[8] = { -2,-1,1,2,2,1,-1,-2 };
int vis[400][400];
int arr[400][400];
int main()
{
	cin >> n >> m >> x >> y;
	vis[x][y] = 1;
	arr[x][y] = 0;
	local l1(x, y);
	q.push(l1);
	while (!q.empty())
	{
		int tx = q.front().lx;
		int ty = q.front().ly;
		q.pop();
		for (int i = 0;i < 8;i++)
		{
			int xi = tx + arrx[i];
			int yi = ty + arry[i];
			if (xi > 0 && xi <= n && yi > 0 && yi <= m && !vis[xi][yi])
			{
				q.push(local(xi, yi));
				vis[xi][yi] = 1;
				arr[xi][yi] = arr[tx][ty] + 1;
			}
		}
	}
	for (int i = 1;i <=n;i++)
	{
		for (int j = 1;j <= m;j++)
		{
			if (arr[i][j] == 0)
			{
				if (i == x && j == y)
				{
					cout << "0" << " ";
				}
				else
				{
					cout << "-1" << " ";
				}
			}
			else
			{
				cout << arr[i][j] << " ";
			}

		}
		cout << endl;
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值