1 条题解
-
0
自动搬运
来自洛谷,原作者为

CYJian
今日はこっちの地方はどしゃぶりの晴天でした,昨日もずっと暇で一日満喫してました搬运于
2025-08-24 21:35:21,当前版本为作者最后更新于2018-04-05 09:44:14,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
(哇一道
大水题没有人发题解)这道题。。。
怎么说呢
实际上很简单,就和直接看上去一样,相信大家都会认为这是一道爆搜题。。
所以我索性就打了一个DFS。。
(代码略丑,不喜勿喷)
#include <bits/stdc++.h> using namespace std; const int fx[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; const int N = 100; int n; int m; int Fx; int Fy; int Tx; int Ty; int res; int s[N + 1][N + 1]; int rem[2][N + 1][N + 1]; bool remem(int x, int y, int tot, int k) { if(tot > rem[0][x][y]) return 1; else if(tot < rem[0][x][y]) return 0; else return k <= rem[1][x][y]; } void dfs(int x, int y, int k, int maxn, int tot, int la) { if(!s[x][y] || x < 1 || y < 1 || x > n || y > m || remem(x, y, tot, k)) return; rem[0][x][y] = tot; rem[1][x][y] = k; if(x == Tx && y == Ty) { if(res < 0) res = tot; else res = min(res, tot); return; } for(int i = 0; i < 4; i++) if(i != la) { if(k == maxn) dfs(x + fx[i][0], y + fx[i][1], 1, maxn, tot + 1, i); } else dfs(x + fx[i][0], y + fx[i][1], min(k + 1, maxn), maxn, tot + 1, i); } int main() { scanf("%d%d%d%d%d%d", &n, &m, &Fx, &Fy, &Tx, &Ty); for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++) scanf("%d", &s[i][j]); for(int i = 1; i <= 10; i++) { res = -1; memset(rem[0], 127, sizeof(rem[0])); memset(rem[1], 0, sizeof(rem[1])); dfs(Fx, Fy, i, i, 0, -1); if(res == -1) break; printf("%d %d\n", i, res); } return 0; }就像这样。。
然后30分,WA与TLE并存。。。
不明所以的我认为是DFS的锅,然后改了一个BFS。。
再贴一波:
#include <bits/stdc++.h> using namespace std; const int fx[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; const int N = 100; int n; int m; int Fx; int Fy; int Tx; int Ty; int res; int s[N + 1][N + 1]; int f[N + 1][N + 1][4]; int dis[N + 1][N + 1][4]; struct Node { int x; int y; int z; }; void print() {/* for(int i = 1; i <= n; i++) { for(int j = 1; j <= m; j++) printf("%-3d ", dis[i][j]); puts(""); } for(int i = 1; i <= n; i++) { for(int j = 1; j <= m; j++) printf("%-3d ", f[i][j]); puts(""); }*/ } void BFS(int k) { queue<Node>q; while(!q.empty()) q.pop(); q.push((Node){Fx, Fy, 0}); q.push((Node){Fx, Fy, 1}); q.push((Node){Fx, Fy, 2}); q.push((Node){Fx, Fy, 3}); f[Fx][Fy][0] = 0; f[Fx][Fy][1] = 0; f[Fx][Fy][2] = 0; f[Fx][Fy][3] = 0; while(!q.empty()) { Node now = q.front(); q.pop(); for(int i = 0; i < 4; i++) { int x = now.x + fx[i][0]; int y = now.y + fx[i][1]; if(x > n || y > m || x < 1 || y < 1) continue; if(dis[x][y][i] || !s[x][y] || (x == Fx && y == Fy)) continue; if(i == now.z) f[x][y][i] = min(k, f[now.x][now.y][now.z] + 1); else { if(f[now.x][now.y][now.z] != k) continue; f[x][y][i] = 1; } q.push((Node){x, y, i}); dis[x][y][i] = dis[now.x][now.y][now.z] + 1; if(x == Tx && y == Ty) { res = dis[x][y][i]; return ; } } } } int main() { scanf("%d%d%d%d%d%d", &n, &m, &Fx, &Fy, &Tx, &Ty); for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++) scanf("%d", &s[i][j]); for(int i = 1; i <= 10; i++) { res = -1; memset(f, 0, sizeof(f)); memset(dis, 0, sizeof(dis)); BFS(i); print(); if(res == -1) break; printf("%d %d\n", i, res); } return 0; }结果还是40分。。。
真是可怕。。。
但是至少没有TLE了。。
然后我就一直找啊找,发现了一个灵异事件:
之前你可能有一个弯绕不过去,
但是有可能你从别的地方绕一下再来这个点的时候就可以过了
上样例:
input: 10 5 4 2 10 3 1 1 1 1 1 0 1 0 0 1 0 1 0 1 1 1 1 0 1 1 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 0 0 1 0 1 0 0 1 0 1 0 0 1 0 1 output: 7 11你的代码是不是输出:
7 17这就是我要说的了
实际上它是这么搞的:

来回走很骚对吧。。
但是并不需要担心复杂度
中间只需要加上一个判断就好
代码中会有提到:
#include <bits/stdc++.h> using namespace std; const int fx[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; const int N = 100; int n; int m; int Fx; int Fy; int Tx; int Ty; int res; int s[N + 1][N + 1]; int f[N + 1][N + 1][4]; int dis[N + 1][N + 1][4]; struct Node { int x; int y; int z; }; void print() {/* for(int i = 1; i <= n; i++) { for(int j = 1; j <= m; j++) printf("%-3d ", dis[i][j]); puts(""); } for(int i = 1; i <= n; i++) { for(int j = 1; j <= m; j++) printf("%-3d ", f[i][j]); puts(""); }*/ } void BFS(int k) { queue<Node>q; while(!q.empty()) q.pop(); q.push((Node){Fx, Fy, 0}); q.push((Node){Fx, Fy, 1}); q.push((Node){Fx, Fy, 2}); q.push((Node){Fx, Fy, 3}); f[Fx][Fy][0] = 0; f[Fx][Fy][1] = 0; f[Fx][Fy][2] = 0; f[Fx][Fy][3] = 0;//0、1、2、3表示从哪个方向来的,f记录连续走了多少步 while(!q.empty()) { Node now = q.front(); q.pop(); for(int i = 0; i < 4; i++) { int x = now.x + fx[i][0]; int y = now.y + fx[i][1]; if(x > n || y > m || x < 1 || y < 1) continue; if(!s[x][y] || (x == Fx && y == Fy)) continue; int a; if(i == now.z) a = min(k, f[now.x][now.y][now.z] + 1); else { if(f[now.x][now.y][now.z] != k) continue; a = 1; } if(dis[x][y][i] && a <= f[x][y][i]) continue; //之前提到的就是这里了 //这里是说如果之前到过并且连续走的步数比之前记录的少就放弃 f[x][y][i] = a; q.push((Node){x, y, i}); dis[x][y][i] = dis[now.x][now.y][now.z] + 1; if(x == Tx && y == Ty) { res = dis[x][y][i]; return ; } } } } int main() { scanf("%d%d%d%d%d%d", &n, &m, &Fx, &Fy, &Tx, &Ty); for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++) scanf("%d", &s[i][j]); for(int i = 1; i <= 10; i++) { res = -1; memset(f, 0, sizeof(f)); memset(dis, 0, sizeof(dis)); BFS(i); print(); if(res == -1) break; printf("%d %d\n", i, res); } return 0; }嗯,这样就可以AC了
- 1
信息
- ID
- 1225
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 4
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者