xjoi题解:P7268 炼身体的路径
时间:1s 空间:256M
题目描述:
有一个 n×m 的地图,空地为'.',高楼为'#',小信的家在 'S'。
小信想找一条锻炼身体的路径,路径需要从家出发,不经过相同的空地,最后回到家。出于锻炼身体的目的,这条路径的长度必须至少为4,也就是说除了终点和起点都是家以外,经过的不同的空地个数至少为 3。
小信想知道这样的路径存不存在。当然,小信无法通过有高楼的地方,所以可能不存在这样的路径。
输入格式:
第一行包含两个整数 n,m。
接下来包含一个 n×m 的地图,地图只包含 '.','#','S' 三种字符。
输出格式:
如果存在锻炼身体的路径,输出"Yes",否则输出"No"。
样例1输入:
4 4
....
#.#.
#S#.
....
样例1输出:
Yes
样例2输入:
4 4
.#..
#.#.
#S#.
....
样例2输出:
No
约定:
对于100%的数据,2≤n,m≤106,4≤n⋅m≤106。
题意:
从点S的位置走,只能往上下左右,判断小信是否能从一条路走出从另外一条路回来。
分析:
典型的走迷宫问题啊!当然用的是dfs,既然是上下左右,所以我们要用一个行动数组表示如何走
int tx[4] = {1, -1, 0, 0};
int ty[4] = {0, 0, -1, 1};
数据范围是个好东西,乍一看(对于100%的数据,2≤n,m≤106,4≤n⋅m≤106。),如果开个数组,肯定会超空间,我们也无法用具体的数来开一个数组,所以我们想到要用一个map来存,我们在输入的时候要一边输入一边记录,将高楼记为1,将空地标为0
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
char ch;
cin >> ch;
if (ch == 'S') {
ii = i;
jj = j;
mp[ {i, j}] = 1;
} else if (ch == '#') {
mp[ {i, j}] = 0;
} else {
mp[ {i, j}] = 1;
}
}
}
在dfs的过程中,要开一个step步数变量,step=0并不是结束条件,用一个mp数组来存放迷宫可走的情况,另外用一个数组flag来存放哪些点走过了。每个点用两个数字来描述,一个表示行号,另一个表示列号。对于某一个点(x,y)要试探四个方向,如果没有走过(数组flag相应的点的值为0)且可以走(数组mp相应点的值为'.')同时不越界,就走过去,再看有没有到达终点,到了终点则输出Yes,否则继续走下去,走不通则输出No。
void dfs(int x, int y, int x_end, int y_end, int step = 0) {
if (x == x_end && y == y_end && step) {
if (step >= 4) {
cout << "Yes";
exit(1);
} else return;
}
if (step && step <= flag[ {x, y}]) {
return;
} else {
flag[ {x, y}] = step;
}
for (int i = 0; i < 4; i++) {
int fx = x + tx[i];
int fy = y + ty[i];
if (fx >= 1 && fx <= n && fy >= 1 && fy <= m && mp[ {fx, fy}]) {
mp[ {fx, fy}] = 0;
dfs(fx, fy, x_end, y_end, step + 1);
mp[ {fx, fy}] = 1;
}
}
return;
}
完整代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int INF = 0x3f3f3f3f;
int tx[4] = {1, -1, 0, 0};
int ty[4] = {0, 0, -1, 1};
int n, m;
map<pair<int, int>, bool>mp;
map<pair<int, int>, int>flag;
void dfs(int x, int y, int x_end, int y_end, int step = 0) {
if (x == x_end && y == y_end && step) {
if (step >= 4) {
cout << "Yes";
exit(1);
} else return;
}
if (step && step <= flag[ {x, y}]) {
return;
} else {
flag[ {x, y}] = step;
}
for (int i = 0; i < 4; i++) {
int fx = x + tx[i];
int fy = y + ty[i];
if (fx >= 1 && fx <= n && fy >= 1 && fy <= m && mp[ {fx, fy}]) {
mp[ {fx, fy}] = 0;
dfs(fx, fy, x_end, y_end, step + 1);
mp[ {fx, fy}] = 1;
}
}
return;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int ii, jj;
cin >> n >> m;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
char ch;
cin >> ch;
if (ch == 'S') {
ii = i;
jj = j;
mp[ {i, j}] = 1;
} else if (ch == '#') {
mp[ {i, j}] = 0;
} else {
mp[ {i, j}] = 1;
}
}
}
dfs(ii, jj, ii, jj);
cout << "No";
}