1.优解思路:
秒啊:如果这条路可以走通,则这条路上所有点都可以走通,反之若不可以,则都不可以。
因为比如一个点走了,没走通,这条路上的点都出不去,假如有别的点走路走到这条死路上的任意一点(路线交叉),岂不是肯定出不去。
所以用一个solve数组记录,当走下一步时,不用return dfs(),直接判断if(dfs()),如果可以, 就标记solve可以,并且返回true。
2.这里我一开始就把solve数组清0了,有保障些。
3.复杂度分析:上一个解答是,假设n行n列,对于一个点,dfs一次,最多把迷宫每个点都走一遍,就是O(n^2)次,如果每个点都要像刚刚那个点一样那么累,那么就是O(n^4)
这个优化后的方法,对于一个点,如果dfs一次,若把迷宫都走遍,那么迷宫每个solve都标注好了,所以就是O(n^2)
#include<iostream>
#include<cstring>
using namespace std;int ans = 0;
char mp[12][12];
bool vis[12][12];
int solve[12][12];
bool dfs(int i, int j) {if (vis[i][j]) return false;if (i < 1 || j < 1 || i>10 || j>10) {return true;}if (solve[i][j] == 1) return true;if (solve[i][j] == 2) return false;//真的得按编译器来,这个只能false不能Falsevis[i][j] = 1;if (mp[i][j] == 'U') {if (dfs(i - 1, j)) {solve[i][j] = 1;return 1;}else {solve[i][j] = 2;return 0;}}if (mp[i][j] == 'D') {if (dfs(i+1, j )) {solve[i][j] = 1;return 1;}else {solve[i][j] = 2;return 0;}}if (mp[i][j] == 'L') {if (dfs(i, j - 1)) {solve[i][j] = 1;return 1;}else {solve[i][j] = 2;return 0;}}if (mp[i][j] == 'R') {if (dfs(i , j+1)) {solve[i][j] = 1;return 1;}else {solve[i][j] = 2;return 0;}}
}
int main() {for (int i = 1; i <= 10; i++) {for (int j = 1; j <= 10; j++) {cin >> mp[i][j];}}memset(solve, 0, sizeof(solve));for (int i = 1; i <= 10; i++) {for (int j = 1; j <= 10; j++) {memset(vis, 0, sizeof(vis));if (dfs(i, j))ans++;}}cout << ans;
}