关于一次MLE

https://www.luogu.com.cn/problem/P1363 一道涉及DFS的题目.

这题我测了两份仅有一处区别的代码.

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;

int n, m;
bool s[1501][1501];
bool ans;
int used[1501][1501][3];

void dfs(int x, int y, int ox, int oy) {
    // printf("%d %d %d %d
", x, y, ox, oy);
    if (ans) return;
    if (used[x][y][2] && (used[x][y][0] != ox || used[x][y][1] != oy)) {
        ans = true;
        return;
    }

    used[x][y][0] = ox, used[x][y][1] = oy, used[x][y][2] = 1;
    int dx[4] = {1, -1, 0, 0}, dy[4] = {0, 0, 1, -1};
    for (int i = 0; i < 4; i++) {
        int nx = (x + n + dx[i]) % n, ny = (y + m + dy[i]) % m;
        int nox = ox + dx[i], noy = oy + dy[i];
        if (s[nx][ny] && (!used[nx][ny][2] || used[nx][ny][0] != nox ||
                          used[nx][ny][1] != noy)) {
            dfs(nx, ny, nox, noy);
        }
    }
}

void solve() {
    int sx, sy;
    ans = false;
    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++) {
            used[i][j][0] = used[i][j][1] = used[i][j][2] = 0;
            char ch;
            cin >> ch;
            if (ch != '#')
                s[i][j] = true;
            else
                s[i][j] = false;
            if (ch == 'S') sx = i, sy = j;
        }

    dfs(sx, sy, sx, sy);
    puts(ans ? "Yes" : "No");
}

int main() {
    // freopen("in.txt", "r", stdin);
    // freopen("out.txt", "w", stdout);
    while (cin >> n >> m) solve();

    return 0;
}
31.34MB
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int dx[4] = {1, -1, 0, 0};
const int dy[4] = {0, 0, 1, -1};
int n, m;
bool s[1501][1501];
bool ans;
int used[1501][1501][3];

void dfs(int x, int y, int ox, int oy) {
    // printf("%d %d %d %d
", x, y, ox, oy);
    if (ans) return;
    if (used[x][y][2] && (used[x][y][0] != ox || used[x][y][1] != oy)) {
        ans = true;
        return;
    }

    used[x][y][0] = ox, used[x][y][1] = oy, used[x][y][2] = 1;
    for (int i = 0; i < 4; i++) {
        int nx = (x + n + dx[i]) % n, ny = (y + m + dy[i]) % m;
        int nox = ox + dx[i], noy = oy + dy[i];
        if (s[nx][ny] && (!used[nx][ny][2] || used[nx][ny][0] != nox ||
                          used[nx][ny][1] != noy)) {
            dfs(nx, ny, nox, noy);
        }
    }
}

void solve() {
    int sx, sy;
    ans = false;
    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++) {
            used[i][j][0] = used[i][j][1] = used[i][j][2] = 0;
            char ch;
            cin >> ch;
            if (ch != '#')
                s[i][j] = true;
            else
                s[i][j] = false;
            if (ch == 'S') sx = i, sy = j;
        }

    dfs(sx, sy, sx, sy);
    puts(ans ? "Yes" : "No");
}

int main() {
    // freopen("in.txt", "r", stdin);
    // freopen("out.txt", "w", stdout);
    while (cin >> n >> m) solve();

    return 0;
}
30.35MB

唯一的区别在这个地方:

// 第一份代码,DFS内部变量
int dx[4] = {1, -1, 0, 0}, dy[4] = {0, 0, 1, -1};
// 第二份代码,全局常量
const int dx[4] = {1, -1, 0, 0};
const int dy[4] = {0, 0, 1, -1};

虽然都能AC,但是本地跑极限数据的时候只有前者爆掉了.

由于dfs会调用很多次,并且每次都会创建新的dx[]和dy[],这个小开销产生的累积效应是非常值得注意的.

所以,不要在dfs里乱写东西.

原文地址:https://www.cnblogs.com/Gaomez/p/14411210.html