题单地址:题单中心-东方博宜OJ
1431. 迷宫的第一条出路
问题描述
已知一 N×N 的迷宫,允许往上、下、左、右四个方向行走,现请你按照左、上、右、下顺序进行搜索,找出第一条从左上角到右下角的路径。
输入
输入数据有若干行,第一行有一个自然数 N(N ≤ 20),表示迷宫的大小;
其后有 N 行数据,每行有 N 个 0 或 1(数字之间没有空格,0 表示可以通过,1 表示不能通过),用以描述迷宫地图。入口在左上角 (1,1)处,出口在右下角(N,N) 处。
所有迷宫保证存在从入口到出口的可行路径。
输出
输出数据仅一行,为按照要求的搜索顺序找到的从入口到出口的第一条路径(搜索顺序:左、上、右、下)。
样例
输入
4
0001
0100
0010
0110
输出
(1,1)->(1,2)->(1,3)->(2,3)->(2,4)->(3,4)->(4,4)
解析:dfs参数包括当前位置和当前步数,使用一个vis数组记录走过的位置,到终点后退出搜索输出vis数组即可。
#include <bits/stdc++.h>
using namespace std;
int n, sum, vis[1005][2], f = 0;
int a[155][155];
int dir[4][2] = {{0, -1}, {-1, 0}, {0, 1}, {1, 0}};
void dfs(int x, int y, int len){
vis[len][0] = x, vis[len][1] = y;
a[x][y] = 1;
if(x == n && y == n){
f = 1;
sum = len;
return ;
}
for(int i = 0; i < 4; i++){
int xx = x + dir[i][0], yy = y + dir[i][1];
if(xx >= 1 && yy >= 1 && xx <= n && yy <= n && a[xx][yy] == 0 && f == 0)
dfs(xx, yy, len + 1);
}
}
int main(){
cin >> n;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= n; j++){
char c;
cin >> c;
a[i][j] = c - '0';
}
}
dfs(1, 1, 1);
for(int i = 1; i <= sum; i++){
printf("(%d,%d)", vis[i][0], vis[i][1]);
if(i != sum)cout << "->";
}
return 0;
}
1360. 卒的遍历
问题描述
在一张 n×m 的棋盘上(如 6 行 7 列)的最左上角 (1,1) 的位置有一个卒。该卒只能向下或者向右走,且卒采取的策略是先向下,下边走到头就向右,请问从 (1,1) 点走到 (n,m) 点可以怎样走,输出这些走法。
输入
两个整数 n,m 代表棋盘大小(3 ≤ n ≤ 8, 3 ≤ m ≤ 8)
输出
卒的行走路线。
样例
输入
3 3
输出
1:1,1->2,1->3,1->3,2->3,3
2:1,1->2,1->2,2->3,2->3,3
3:1,1->2,1->2,2->2,3->3,3
4:1,1->1,2->2,2->3,2->3,3
5:1,1->1,2->2,2->2,3->3,3
6:1,1->1,2->1,3->2,3->3,3
解析:dfs参数包括当前位置和当前步数,使用一个vis数组记录走过的位置,并标记该点走过,到终点后输出vis数组即可。
#include <bits/stdc++.h>
using namespace std;
int n, m, vis[10005][2], k;
int a[155][155];
int dir[4][2] = {{1, 0}, {0, 1}, {0, -1}, {-1, 0}};
void dfs(int x, int y, int len){
vis[len][0] = x, vis[len][1] = y;
if(x == n && y == m){
k++;
cout << k << ":";
for(int i = 1; i <= len; i++){
printf("%d,%d", vis[i][0], vis[i][1]);
if(i != len)cout << "->";
else cout << endl;
}
}
for(int i = 0; i < 2; i++){
int xx = x + dir[i][0], yy = y + dir[i][1];
if(xx >= 1 && yy >= 1 && xx <= n && yy <= m && a[xx][yy] == 0){
a[xx][yy] = 1;
dfs(xx, yy, len + 1);
a[xx][yy] = 0;
}
}
}
int main(){
cin >> n >> m;
dfs(1, 1, 1);
}
1362. 马的遍历
问题描述
中国象棋半张棋盘如图(a)所示。马自左下角往右上角跳。
今规定只许往右跳,不许往左跳,且要求马跳的方式按照(b)图顺时针深度优先递归。比如图(a)中所示为一种跳行路线。如果马要从 0,0 点,跳到 4,8 点,前 6 种跳法的打印格式如下,请参考前 6 种跳的方式,输出马从 0,0 点到 4,8 点所有可能的跳的路线。
1:0,0->2,1->4,2->3,4->4,6->2,7->4,8
2:0,0->2,1->4,2->3,4->1,5->3,6->4,8
3:0,0->2,1->4,2->3,4->1,5->2,7->4,8
4:0,0->2,1->4,2->2,3->4,4->3,6->4,8
5:0,0->2,1->4,2->2,3->4,4->2,5->4,6->2,7->4,8
6:0,0->2,1->4,2->2,3->4,4->2,5->0,6->2,7->4,8
输入
无
输出
1:0,0->2,1->4,2->3,4->4,6->2,7->4,8
2:0,0->2,1->4,2->3,4->1,5->3,6->4,8
3:0,0->2,1->4,2->3,4->1,5->2,7->4,8
4:0,0->2,1->4,2->2,3->4,4->3,6->4,8
5:0,0->2,1->4,2->2,3->4,4->2,5->4,6->2,7->4,8
6:0,0->2,1->4,2->2,3->4,4->2,5->0,6->2,7->4,8
解析:dfs参数包括当前位置和当前步数,使用一个vis数组记录走过的位置,并标记该点走过,到终点后输出vis数组即可。注意马的前进方向和步数。
#include <bits/stdc++.h>
using namespace std;
int n, m, vis[10005][2], k;
int a[155][155];
int dir[4][2] = {{2, 1}, {1, 2}, {-1, 2}, {-2, 1}};
void dfs(int x, int y, int len){
vis[len][0] = x, vis[len][1] = y;
if(x == 4 && y == 8){
k++;
cout << k << ":";
for(int i = 1; i <= len; i++){
printf("%d,%d", vis[i][0], vis[i][1]);
if(i != len)cout << "->";
else cout << endl;
}
}
for(int i = 0; i < 4; i++){
int xx = x + dir[i][0], yy = y + dir[i][1];
if(xx >= 0 && yy >= 0 && xx <= 4 && yy <= 8 && a[xx][yy] == 0){
a[xx][yy] = 1;
dfs(xx, yy, len + 1);
a[xx][yy] = 0;
}
}
}
int main(){
dfs(0, 0, 1);
}
1739. 迷宫的所有路径
问题描述
已知一 N×N 的迷宫,允许往上、下、左、右四个方向行走,且迷宫中没有任何障碍,所有的点都可以走。
现请你按照右、下、左、上顺序进行搜索,找出从左上角到右下角的所有路径。
输入
输入一个整数 N(N ≤ 5)代表迷宫的大小。
输出
按右、下、左、上搜索顺序探索迷宫,输出从左上角 (1,1) 点走到右下角 (N,N) 点的所有可能的路径。
样例
输入
3
输出
1:1,1->1,2->1,3->2,3->3,3
2:1,1->1,2->1,3->2,3->2,2->3,2->3,3
3:1,1->1,2->1,3->2,3->2,2->2,1->3,1->3,2->3,3
4:1,1->1,2->2,2->2,3->3,3
5:1,1->1,2->2,2->3,2->3,3
6:1,1->1,2->2,2->2,1->3,1->3,2->3,3
7:1,1->2,1->2,2->2,3->3,3
8:1,1->2,1->2,2->3,2->3,3
9:1,1->2,1->2,2->1,2->1,3->2,3->3,3
10:1,1->2,1->3,1->3,2->3,3
11:1,1->2,1->3,1->3,2->2,2->2,3->3,3
12:1,1->2,1->3,1->3,2->2,2->1,2->1,3->2,3->3,3
解析:dfs参数包括当前位置和当前步数,使用一个vis数组记录走过的位置,并标记该点走过,到终点后输出vis数组即可。注意马的前进方向和步数。
#include <bits/stdc++.h>
using namespace std;
int n, m, vis[10005][2], k;
int a[155][155];
int dir[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
void dfs(int x, int y, int len){
vis[len][0] = x, vis[len][1] = y;
if(x == n && y == n){
k++;
cout << k << ":";
for(int i = 1; i <= len; i++){
printf("%d,%d", vis[i][0], vis[i][1]);
if(i != len)cout << "->";
else cout << endl;
}
}
for(int i = 0; i < 4; i++){
int xx = x + dir[i][0], yy = y + dir[i][1];
if(xx >= 1 && yy >= 1 && xx <= n && yy <= n && a[xx][yy] == 0){
a[xx][yy] = 1;
dfs(xx, yy, len + 1);
a[xx][yy] = 0;
}
}
}
int main(){
cin >> n;
a[1][1] = 1;
dfs(1, 1, 1);
}
1411. 迷宫的路径
问题描述
Mitch老鼠在森林里游玩,不小心走进了一个迷宫里面,这个迷宫是一个 n 行 m 列的矩阵,迷宫中有些格子是可以走的,有些格子是不能走的,能走的格子用 o
(小写字母 o
)表示,不能走的格子用 #
表示。
Mitch选择走出迷宫的策略是:先向右,如果右边走不通则选择向下,如果下边走不通则选择向左,如果左边走不通则选择向上;如果四个方向都走不通,则后退选择其他能走的路径。
Mitch从类似下图所示的迷宫的左上角 (1,1) 点进入迷宫(请注意:入口 1,1 和出口的 n,m 点都不是 #
),请问Mitch有哪些方法可以走出迷宫,走到 (n,m) 点;请编程求出所有可能的路径,输出这些路径,如果不存在任何的路径可以走出迷宫,请输出 no
。
输入
第一行包含两个整数 n 和 m ,中间用单个空格隔开,代表迷宫的行和列的数量。
接下来 n 行,每行 m 个字符,描述迷宫地图。字符只有o
或 #
两种,o
代表这个格子可以走,#
代表这个格子不能走。( 4 ≤ n, m ≤ 10 )
输出
请按照Mitch选择的走出迷宫的策略,输出所有可能的路径,输出形式请参考样例输出的形式。
如果不存在任何的路径可以走出迷宫,请输出 no
。
样例
输入
6 5
ooooo
o####
ooooo
#oo#o
oooo#
o#ooo
输出
1:1,1->2,1->3,1->3,2->3,3->4,3->5,3->5,4->6,4->6,5
2:1,1->2,1->3,1->3,2->3,3->4,3->5,3->6,3->6,4->6,5
3:1,1->2,1->3,1->3,2->3,3->4,3->4,2->5,2->5,3->5,4->6,4->6,5
4:1,1->2,1->3,1->3,2->3,3->4,3->4,2->5,2->5,3->6,3->6,4->6,5
5:1,1->2,1->3,1->3,2->4,2->4,3->5,3->5,4->6,4->6,5
6:1,1->2,1->3,1->3,2->4,2->4,3->5,3->6,3->6,4->6,5
7:1,1->2,1->3,1->3,2->4,2->5,2->5,3->5,4->6,4->6,5
8:1,1->2,1->3,1->3,2->4,2->5,2->5,3->6,3->6,4->6,5
解析:dfs参数包括当前位置和当前步数,使用一个vis数组记录走过的位置,并标记该点走过,到终点后输出vis数组即可。
#include <bits/stdc++.h>
using namespace std;
int n, m, vis[100005][2], k;
char a[155][155];
int dir[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
void dfs(int x, int y, int len){
vis[len][0] = x, vis[len][1] = y;
if(x == n && y == m){
k++;
cout << k << ":";
for(int i = 1; i <= len; i++){
printf("%d,%d", vis[i][0], vis[i][1]);
if(i != len)cout << "->";
else cout << endl;
}
}
for(int i = 0; i < 4; i++){
int xx = x + dir[i][0], yy = y + dir[i][1];
if(xx >= 1 && yy >= 1 && xx <= n && yy <= n && a[xx][yy] == 'o'){
a[xx][yy] = '#';
dfs(xx, yy, len + 1);
a[xx][yy] = 'o';
}
}
}
int main(){
cin >> n >> m;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
cin >> a[i][j];
}
}
a[1][1] = '#';
dfs(1, 1, 1);
if(k == 0)cout << "no";
}