cf Educational Codeforces Round 53 C. Vasya and Robot

原題:
C. Vasya and Robot
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
Vasya has got a robot which is situated on an infinite Cartesian plane, initially in the cell (0,0). Robot can perform the following four kinds of operations:

U — move from (x,y) to (x,y+1);
D — move from (x,y) to (x,y−1);
L — move from (x,y) to (x−1,y);
R — move from (x,y) to (x+1,y).
Vasya also has got a sequence of n operations. Vasya wants to modify this sequence so after performing it the robot will end up in (x,y).

Vasya wants to change the sequence so the length of changed subsegment is minimum possible. This length can be calculated as follows: maxID−minID+1, where maxID is the maximum index of a changed operation, and minID is the minimum index of a changed operation. For example, if Vasya changes RRRRRRR to RLRRLRL, then the operations with indices 2, 5 and 7 are changed, so the length of changed subsegment is 7−2+1=6. Another example: if Vasya changes DDDD to DDRD, then the length of changed subsegment is 1.

If there are no changes, then the length of changed subsegment is 0. Changing an operation means replacing it with some operation (possibly the same); Vasya can’t insert new operations into the sequence or remove them.

Help Vasya! Tell him the minimum length of subsegment that he needs to change so that the robot will go from (0,0) to (x,y), or tell him that it’s impossible.

Input
The first line contains one integer number n (1≤n≤2⋅105) — the number of operations.

The second line contains the sequence of operations — a string of n characters. Each character is either U, D, L or R.

The third line contains two integers x,y (−109≤x,y≤109) — the coordinates of the cell where the robot should end its path.

Output
Print one integer — the minimum possible length of subsegment that can be changed so the resulting sequence of operations moves the robot from (0,0) to (x,y). If this change is impossible, print −1.

Examples
input
5
RURUU
-2 3
output
3
input
4
RULR
1 1
output
0
input
3
UUU
100 100
output
-1
Note
In the first example the sequence can be changed to LULUU. So the length of the changed subsegment is 3−1+1=3.

In the second example the given sequence already leads the robot to (x,y), so the length of the changed subsegment is 0.

In the third example the robot can’t end his path in the cell (x,y).

中文:

給你一個一個操作字符串,包含UDLR,分別表示爲向上向下向左向右移動,然後給你一個座標(x,y),讓你去修改一段區間的字符串,使得能從原點走到座標(x,y),輸出這個區間的最小長度,如果不能修改輸出-1

代碼:

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
const int maxn=200001;

int x[maxn],y[maxn],n,X,Y;
string s;

int main()
{
    ios::sync_with_stdio(false);
    while(cin>>n)
    {
        cin>>s;
        cin>>X>>Y;
        if(abs(X)+abs(Y)>n||(abs(X)+abs(Y)-n)%2)
        {
            cout<<-1<<endl;
            continue;
        }
        memset(x,0,sizeof(x));
        memset(y,0,sizeof(y));
        for(int i=1;i<=n;i++)
        {
            if(s[i-1]=='U')
            {
                y[i]=y[i-1]+1;
                x[i]=x[i-1];
            }
            if(s[i-1]=='D')
            {
                y[i]=y[i-1]-1;
                x[i]=x[i-1];
            }
            if(s[i-1]=='R')
            {
                x[i]=x[i-1]+1;
                y[i]=y[i-1];
            }
            if(s[i-1]=='L')
            {
                x[i]=x[i-1]-1;
                y[i]=y[i-1];
            }
        }
        int ans=n;
        int L=0,R=n,tx,ty;
        int m;
        while(L<=R)
        {
            m=(L+R)/2;
            for(int i=1;i<=n-m+1;i++)
            {
                tx=x[n]-x[i+m-1]+x[i-1];
                ty=y[n]-y[i+m-1]+y[i-1];
                if(abs(X-tx)+abs(Y-ty)>m||(m-abs(X-tx)-abs(Y-ty))%2)
                {
                    if(n-m+1==i)
                        L=m+1;
                }
                else
                {
                    R=m-1;
                    ans=min(ans,m);
                    break;
                }
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}

解答:

如果要到達(x,y),那麼只需要橫向移動x,縱向移動y即可。所以,如果枚舉修改的區間,那麼要知道非修改部分有多少橫向移動和縱向移動的值。使用預處理前綴和x[i]和y[i]來記錄前i個字符串當中橫向移動了多少,和縱向移動了多少步。
最後,使用二分或者尺取法枚舉區間大小,由於修改區間的中的操作可以變成任意操作,所以只要非區間部分的橫向,縱向移動步數和區間長度的關係即可。如果非區間部分的操作在橫向和縱向分別已經走了tx和ty,那麼橫向和縱向剩餘的步數abs(x-tx)與abs(x-ty)起碼要小於等於修改區間的長度才能實現,此外,如果修改區間的長度減去abs(x-tx)與abs(x-ty)是奇數,那麼會多餘一個操作或者缺一個操作,使得無法達到(x,y),根據這兩個條件來對區間進行二分即可。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章