Educational Codeforces Round 53 (Rated for Div. 2) C. Vasya and Robot 二分+前后缀预处理

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xiang_6/article/details/83686299

题意:

给定长度为n的字符串,每个字符表示朝上下左右四个方向前进,给定一个目标位置,找一个最小的区间,使得改变这个区间的若干个字符,使得整个串的操作能到达目标位置只需要输出最小区间长度

思路:

首先暴力的想法就是枚举所有的区间,这样这个区间两边就会有一些操作不会改变,然后我们根据这些操作得到一个位置,跟目标位置比较,看看我们能否通过设置这个区间达到目标位置,显然复杂度很高;

然后就可以想到二分,二分区间长度,然后对于当前区间长度,枚举开始位置,检查是否可以到达目标位置,这样的话还是按照上述暴力的思路,我们得知道不改变的操作能到达的位置,这就需要我们预处理前缀和后缀能对上下左右四个方向做出的贡献,可以得到一个“位置”,然后检查是否可行

#include<bits/stdc++.h>

using namespace std;

#define out fflush(stdout)
#define fast ios::sync_with_stdio(0),cin.tie(0);

#define FI first
#define SE second

typedef long long ll;
typedef pair<int,int> P;

const int maxn = 2e5 + 7;
const int INF = 0x3f3f3f3f;


int n, x, y;
char s[maxn];
int x1[maxn], y1[maxn];
int x2[maxn], y2[maxn];


bool ok(int len) {
    for(int i = 1; i <= n; ++i) {
        int j = i + len - 1;
        if(j > n) break;
        int dx = x1[i-1] + x2[j + 1], dy = y1[i-1] + y2[j+1];
//        cout << i << " : " << dx << " +++ " << dy << endl;
        int cnt = abs(dx-x) + abs(dy-y);
        if(cnt <= len && (len-cnt) % 2 == 0) return true;
    }
    return false;
}
void init() {
    x1[0] = 0, y1[0] = 0;
    for(int i = 1; i <= n; ++i) {
        if(s[i] == 'U') {
            x1[i] = x1[i-1];
            y1[i] = y1[i-1] + 1;
        }
        if(s[i] == 'D') {
            x1[i] = x1[i-1];
            y1[i] = y1[i-1] - 1;
        }
        if(s[i] == 'L') {
            x1[i] = x1[i-1] - 1;
            y1[i] = y1[i-1];
        }
        if(s[i] == 'R') {
            x1[i] = x1[i-1] + 1;
            y1[i] = y1[i-1];
        }
    }
    x2[n+1] = 0, y2[n+1] = 0;
    for(int i = n; i >= 1;--i) {
        if(s[i] == 'U') {
            x2[i] = x2[i+1];
            y2[i] = y2[i+1] + 1;
        }
        if(s[i] == 'D') {
            x2[i] = x2[i+1];
            y2[i] = y2[i+1] - 1;
        }
        if(s[i] == 'L') {
            x2[i] = x2[i+1] - 1;
            y2[i] = y2[i+1];
        }
        if(s[i] == 'R') {
            x2[i] = x2[i+1] + 1;
            y2[i] = y2[i+1];
        }
    }
}
int main() {
    scanf("%d", &n);
    scanf("%s", s+1);
    scanf("%d%d", &x, &y);
    if(abs(x) + abs(y) > n) {
        return 0*puts("-1");
    }
    init();
    int l = 0, r = n, ans = -1;
    while(l <= r) {
        int mid = (l + r) / 2;
//        cout << mid << "  : ";
        if(ok(mid)) {
//                cout << " YES " << endl;
            ans = mid;
            r = mid - 1;
        }
        else {
//            cout << " NO " << endl;
            l = mid + 1;
        }
    }
    printf("%d\n", ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/xiang_6/article/details/83686299