Robot on the Board 2(tarjan,dfs,dp)

传送门

题解:这个题思想不难,难的是实现,用 d [ i ] [ j ] d[i][j] d[i][j]来表示从第 i i i行第 j j j列这个格子出发所能跑的距离

然后看下下面2种情况:

第一种情况就是从该条路上的某个格子出发,是个会走出去的路线

在这里插入图片描述

第二种情况就是这条路上可能会有个环

在这里插入图片描述

那么其实说到底就是这样:可以先分别找出图中所有的环(考虑tarjan算法),然后每个环路上的值就是这个环的大小,接着直接dfs就可以。

但是这个题这样写是会爆内存的,可以直接把找环和更新答案维护到一个dfs中去,并且用一个ins数组来表示此时该点是否已经入栈。

#include <bits/stdc++.h>
using namespace std;
#define db double
#define ll long long
#define pii pair<int,int>
#define rush() int T; scanf("%d", &T); while (T--)
const int N = 2e3 + 3;
const int M = (N << 2);
const int P = 1e9 + 7;
char grid[N][N];
bool vis1[N][N], ins[N][N];
int n, m, d[N][N];
bool safe(int x, int y)
{
    if (x < 1 || x > n || y < 1 || y > m || vis1[x][y]) return false;
    return true;
}
bool safe1(int x, int y)
{
    if (x < 1 || x > n || y < 1 || y > m) return 0;
    return true;
}
void dfs(int x, int y)
{
    if (ins[x][y] == 1) {
        int r = x, c = y, num = 0;
        do {
            num ++;
            if (grid[r][c] == 'L') c--;
            else if (grid[r][c] == 'R') c++;
            else if (grid[r][c] == 'U') r--;
            else if (grid[r][c] == 'D') r++;
            if (!safe(r, c)) break;
            if (r == x && c == y) break;
            if (vis1[r][c]) break;
        } while (233);
        r = x, c = y;
        do {
            d[r][c] = num;
            ins[r][c] = 0;
            if (num > 1) vis1[r][c] = 1;
            if (grid[r][c] == 'L') c--;
            else if (grid[r][c] == 'R') c++;
            else if (grid[r][c] == 'U') r--;
            else if (grid[r][c] == 'D') r++;
            if (!safe(r, c)) break;
            if (r == x && c == y) break;
            if (vis1[r][c]) break;
        } while (233);
        return ;
    }
    ins[x][y] = 1;
    if (grid[x][y] == 'L') {
        if (safe(x, y - 1)){
            dfs(x, y - 1);
        }
    } else if (grid[x][y] == 'R') {
        if (safe(x, y + 1)){
            dfs(x, y + 1);
        }
    } else if (grid[x][y] == 'U') {
        if (safe(x - 1, y)){
            dfs(x - 1, y);
        }
    } else if (grid[x][y] == 'D') {
        if (safe(x + 1, y)){
            dfs(x + 1, y);
        }
    }
    if (ins[x][y] && vis1[x][y] != 1) {
        d[x][y] = 1;
        vis1[x][y] = 1;
        if (grid[x][y] == 'L') {
            if (safe1(x, y - 1)) d[x][y] += d[x][y - 1];
        } else if (grid[x][y] == 'R') {
            if (safe1(x, y + 1)) d[x][y] += d[x][y + 1];
        } else if (grid[x][y] == 'U') {
            if (safe1(x - 1, y)) d[x][y] += d[x - 1][y];
        } else if (grid[x][y] == 'D') {
            if (safe1(x + 1, y)) d[x][y] += d[x + 1][y];
        }
    }
    return ;
}
int main()
{
    rush() {
        scanf("%d%d", &n, &m);
        for (int i = 1; i <= n; i++) scanf("%s", grid[i] + 1);
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                vis1[i][j] = d[i][j] = ins[i][j] = 0;
            }
         }
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                if (vis1[i][j]) continue;
                dfs(i, j);
            }
        }
        int ans = 0, ansx, ansy;
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                if (d[i][j] > ans) {
                    ans = d[i][j];
                    ansx = i;
                    ansy = j;
                }
            }
        }
        cout << ansx << " " << ansy << " " << ans << endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值