Codeforces Round #753 (Div. 3)(记忆化搜索+图论)

E. Robot on the Board 1

题意

有一个字符串,求从哪一点开始出发可以走尽可能多的方格,如果出了边界视为结束

分析

可以维护两个变量 \(dx\ dy\)

如果 \(dy>0\) 那么说明机器人向右走,所以将后面的 \(dy\) 列置为 \(1\),如果 \(dy<0\) 则将前面的 \(dy\) 列置为 \(1\)

\(dx\) 同理,最后找到没有被访问过的行列即可

如此糟粕的思路在机器人必出界的情况下还需要回滚

根据上述思路,同样维护 \(dx\ dy\),分别代表 \(x\ y\) 方向上需要的长度

如果 \(dx=n\) ,说明刚刚出界,这时在 \(x\) 方向上只有一行可以选择来保证答案是最大的

    int n, m, k, _;
    // int a[N];
    string s;
 
int calc(int opt, int len)
{
    int minn = 0, maxx = 0;
    int now = 0; 
    for(int i = 0; s[i]; i ++){
        if(opt){
            if(s[i] == 'R'){
                now ++;
            }
            else if(s[i] == 'L'){
                now --;
            }
        }
        else{
            if(s[i] == 'U'){
                now --;
            }
            else if(s[i] == 'D'){
                now ++;
            }
        }
        if(maxx - minn + 1 >= len) break;
        minn = min(minn, now);
        maxx = max(maxx, now);
    }
    return - minn + 1;
}
 
signed main()
{
    // IOS;
    rush(){
        cin >> n >> m;
        cin >> s;
        int x = calc(0, n), y = calc(1, m);
        cout << x << " " << y << endl;
    }
    // PAUSE;
    return 0;
}

F. Robot on the Board 2

题意

有一张地图,求从那个点出发可以走尽可能多的格子,如果出界或者走到原来经过的格子视为出界,输出起点与最远距离

分析

妥妥的记忆化搜索, \(a[x][y]\) 定义为 \((x,y)\) 开始出发可以走过的最远距离

题目中的样例提示存在环的情况,环内的每一个点的最远距离都为环的长度

const int N = 2e3 + 5;
 
    int n, m, k, _;
    int a[N][N];
    char s[N][N];
    bool vis[N][N];
    pii stk[N * N];
    int p;

int dfs(int x, int y)
{
    stk[++ p] = {x, y};
    if(x <= 0 || x > n) return 0;
    if(y <= 0 || y > m) return 0;
    if(vis[x][y]) return a[x][y];

    vis[x][y] = 1;
    if(s[x][y] == 'U'){
        a[x][y] += dfs(x - 1, y) + 1;
    }
    else if(s[x][y] == 'D'){
        a[x][y] += dfs(x + 1, y) + 1;
    }
    else if(s[x][y] == 'L'){
        a[x][y] += dfs(x, y - 1) + 1;
    }
    else{
        a[x][y] += dfs(x, y + 1) + 1;
    }
    return a[x][y];
}

void update()
{
    pii top = stk[p];
    for(int k = p - 1; k; k --){
        if(stk[k] == top){
            for(int i = k; i <= p; i ++){
                int x = stk[i].fi, y = stk[i].se;
                a[x][y] = p - k;
            }
            break;
        }
    }
}

signed main()
{
    // IOS;
    rush(){
        sdd(n, m);
        for(int i = 1; i <= n; i ++){
            for(int j = 1; j <= m; j ++){
                sc(s[i][j]);
            }
        }
        for(int i = 1; i <= n; i ++){
            for(int j = 1; j <= m; j ++){
                if(a[i][j] == 0){
                    p = 0;
                    dfs(i, j);
                    update();
                }
            }
        }
        int x = 0, y = 0;
        for(int i = 1; i <= n; i ++){
            for(int j = 1; j <= m; j ++){
                if(a[x][y] < a[i][j]){
                    x = i;
                    y = j;
                }
            }
        }
        printf("%d %d %d\n", x, y, a[x][y]);
        rep(i, 1, n) rep(j, 1, m) a[i][j] = vis[i][j] = 0;
    }
    // PAUSE;
    return 0;
}
posted @ 2021-11-04 17:05  Bcoi  阅读(76)  评论(0)    收藏  举报