1.P1605 迷宫
题目描述
给定一个 N×M 方格的迷宫,迷宫里有 T 处障碍,障碍处不可通过。
在迷宫中移动有上下左右四种方式,每次只能移动一个方格。数据保证起点上没有障碍。
给定起点坐标和终点坐标,每个方格最多经过一次,问有多少种从起点坐标到终点坐标的方案。
输入格式
第一行为三个正整数 N,M,T 分别表示迷宫的长宽和障碍总数。
第二行为四个正整数 SX,SY,FX,FY,SX,SY 代表起点坐标,FX,FY 代表终点坐标。
接下来 T 行,每行两个正整数,表示障碍点的坐标。
输出格式
输出从起点坐标到终点坐标的方案总数。
输入输出样例
输入
2 2 1 1 1 2 2 1 2
输出
1
说明/提示
对于 100% 的数据,1≤N,M≤5,1≤T≤10,1≤SX,FX≤N,1≤SY,FY≤M。
从迷宫入口找到出口很明显是要用深搜来做,而且人家要求输出解的个数,所以就每次搜索以后就给他回溯一下,一直找直到碰到出口就结束,顺便把解的个数++,具体的做法我都在代码里面写成注释了,最后输出这个解的个数就AC了
#include <iostream>
using namespace std;
int sum = 0;
int x, y, mnt, sx, sy, fx, fy, arr[7][7] = {0};
void DFS(int x,int y) {
arr[x][y] = 2;//标记这个点表示走过
if(x == fx&&y == fy){//遇到出口就sum++并且return回去
sum++;
return;
}
// if(arr[x-1][y]==0){//如果没走过并且没有障碍
// DFS(x-1,y);//继续深搜
// arr[x-1][y] = 0;//回溯
// }//下面都是一样的不过合成到一行了
if(arr[x-1][y]==0){DFS(x-1,y);arr[x-1][y] = 0;}
if(arr[x+1][y]==0){DFS(x+1,y);arr[x+1][y] = 0;}
if(arr[x][y+1]==0){DFS(x,y+1);arr[x][y+1] = 0;}
if(arr[x][y-1]==0){DFS(x,y-1);arr[x][y-1] = 0;}
}
int main() {
//一堆输入
cin >> x >> y >> mnt;
cin >> sx >> sy >> fx >> fy;
//地图的初始化
for (int i = 0; i <= x + 1; i++) {
for (int j = 0; j <= y + 1; j++) {
if (i == 0 || i == x + 1 || j == 0 || j == y + 1 )
arr[i][j] = 1;//墙都设成1
}
}
int tempx, tempy;
for (int i = 0; i < mnt; i++) {
cin >> tempx >> tempy;
arr[tempx][tempy] = 1;//障碍和墙一样看待,都不能走,设成1
}
// for (int i = 0; i <= x + 1; i++) {
// for (int j = 0; j <= y + 1; j++) {
// cout << arr[i][j] << ' ';
// }
// cout << endl;
// }//输出地图检测输入是否正确
//开搜
DFS(sx,sy);
cout << sum;
return 0;
}
2.P1443 马的遍历
题目描述
有一个 n×m 的棋盘,在某个点 (x, y) 上有一个马,要求你计算出马到达棋盘上任意一个点最少要走几步。
输入格式
输入只有一行四个整数,分别为 n, m, x, y。
输出格式
一个 n×m 的矩阵,代表马到达某个点最少要走几步(不能到达则输出 −1)。
输入输出样例
输入
3 3 1 1
输出
0 3 2 3 -1 1 2 1 4
说明/提示
数据规模与约定
对于全部的测试点,保证 1≤x≤n≤400,1≤y≤m≤400。
这个题一眼广搜,就是把遍历到的节点的下一步能走的节点给他放到队列里面,然后把这个节点赋值,再走到下一个节点,一层一层的搜索,直到队列里面没有新成员了,走不下去了,就可以退出了,直接把这个矩阵输出就OK,还是具体操作写在注释里,代码贴上
#include <iostream>
#include <cstring>
using namespace std;
#define MAXX 405
#define MAXY 405
#define DUILIE 164025
int main()
{
//准备工作
char arr[MAXX][MAXY];
memset(arr,-1,MAXX*MAXY);//把这个矩阵初始化成-1表示没有走过
int b[2][DUILIE];//用一个二维数组当队列了,第一行存x值,第二行存y值
int dx[8]={-1,-2,-2,-1,1,2,2,1};
int dy[8]={2,1,-1,-2,2,1,-1,-2};//把八个方向用数组存一下,后面直接遍历这个数组就OK
int start = 0,end = 0;//用给队列的两个变量,存队列的头尾
int n,m,x,y,step=0;//矩阵大小和初始位置都在这里,step是步数
//开始输入
cin >> n >> m >> x >> y ;
arr[x][y] = 0;//起始位置设成0
b[0][end] = x;
b[1][end++] = y;//把起始位置压入队列
//广搜开始
while(start!=end){//只要队列里还有元素
int temp = end;
for(;start!=temp;start = (start+1)%DUILIE){
//把相邻的位置压入队列
for(int i=0;i<8;i++)
{
int nx=b[0][start]+dx[i],ny=b[1][start]+dy[i];
if(nx>0&&nx<=n&&ny>0&&ny<=m&&arr[nx][ny]==-1){
b[0][end] = nx;
b[1][end] = ny;
end = (end+1)%DUILIE;
arr[nx][ny] = -2;//一定要设成跟-1不一样的区分一下,不然有可能多次压入
}
}
arr[b[0][start]][b[1][start]] = step;//赋值
}
step++;//步数++
}
//简单输出
for(int i = 1;i <= n;i++){
for(int j = 1;j <= m;j++){
printf("%-5d",arr[i][j]);
}cout << endl;
}
return 0;
}