Codeforces 1073C——思维

版权声明:欢迎大家转载,转载请注明出处 https://blog.csdn.net/hao_zong_yin/article/details/83660762

题意:

一个机器人在(0,0),给出n个指令,指令的种类为L R D U,分别代表左移一步 右移一步 下移一步 上移一步,现在给出一个终点(

x,y),要通过改变序列中的一些指令使得机器人最终停在(x,y),并使得花费最小,输出最小花费(原本就能达到输出0,无解输出-1),只允许把一个指令更改为任意一个指令,不允许插入或者删除指令,花费的计算为改变指令的最大小标减去改变指令的最小下标+1,即区间[最小指令下标,最大指令下标]的长度

1<=n<=2e5,-1e9<=x,y<=1e9

思路:

首先注意到我们要求的实际上是一个最小区间长度,并且这个区间里的任意指令我们都可以做更改从而使得我们最终到达(x,y),并且注意到这个区间长度越长对我们越有利,所以可以二分区间长度进行判断。

如何判断一个长度为len的区间是否合法呢?首先我们要枚举区间的位置,然后计算除了这个区间以外的那些位置上的操作可以使机器人到达的坐标(这需要维护一个前缀和和后缀和),与(x,y)做差绝对值就可以得到两个数△x △y,我们现在要判断的就是是否能通过改变当前区间的某些操作使得我们可以恰好凑出△x △y,对于这点我们只要判断len>=△x+△y && (len-△x-△y)%2==0即可

#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 10;
int n;
char s[maxn];
int x, y;
int prex[maxn], prey[maxn];
int sufx[maxn], sufy[maxn];
bool judge(int len) {
    for (int i = 1; i + len - 1 <= n; i++) {
        int l = i-1, r = i+len-1+1;
        int xx = prex[l] + sufx[r];
        int yy = prey[l] + sufy[r];
        int dx = abs(x - xx);
        int dy = abs(y - yy);
        if (len >= dx + dy && (len-dx-dy)%2 == 0) {
            return true;
        }
    }
    return false;
}
int solve() {
    int l = 1, r = n;
    while (l <= r) {
        int mid = (l + r)>>1;
        if (judge(mid)) r = mid - 1;
        else l = mid + 1;
    }
    if (!judge(l)) return -1;
    return l;
}
int main() {
    scanf("%d", &n);
    scanf("%s", s+1);
    scanf("%d%d", &x, &y);
    memset(prex, 0, sizeof(prex));
    memset(prey, 0, sizeof(prey));
    memset(sufx, 0, sizeof(sufx));
    memset(sufy, 0, sizeof(sufy));
    for (int i = 1; i <= n; i++) {
        if (s[i] == 'L') {
            prex[i] = prex[i-1]-1;
            prey[i] = prey[i-1];
        }
        else if (s[i] == 'R') {
            prex[i] = prex[i-1]+1;
            prey[i] = prey[i-1];
        }
        else if (s[i] == 'D') {
            prex[i] = prex[i-1];
            prey[i] = prey[i-1]-1;
        }
        else {
            prex[i] = prex[i-1];
            prey[i] = prey[i-1]+1;
        }
    }
    for (int i = n; i >= 1; i--) {
        if (s[i] == 'L') {
            sufx[i] = sufx[i+1]-1;
            sufy[i] = sufy[i+1];
        }
        else if (s[i] == 'R') {
            sufx[i] = sufx[i+1]+1;
            sufy[i] = sufy[i+1];
        }
        else if (s[i] == 'D') {
            sufx[i] = sufx[i+1];
            sufy[i] = sufy[i+1]-1;
        }
        else {
            sufx[i] = sufx[i+1];
            sufy[i] = sufy[i+1]+1;
        }
    }
    if (prex[n] == x && prey[n] == y) {
        printf("%d\n", 0);
    }
    else printf("%d\n", solve());
    return 0;
}

猜你喜欢

转载自blog.csdn.net/hao_zong_yin/article/details/83660762