codeforces 1073C. Vasya and Robot
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).
給定一個字串,字串中每一元素表示在平面直角座標系的一個移動,現在求一個最小連續區間,要求這個只在這個區間改動,就可使機器人從原點移動到指定位置。 首先考慮在什麼情況下,無論如何改動這個字串都不能到達指定位置
- 字串長度小於從原點到指定位置的距離
- 字串長度與從原點到指定位置的奇偶性不同 如給定長度為0,到達位置為(1,0)。這樣一定不會到達指定位置,同理,對字串和原點到指定位置同時加上一個偶數,仍然無法到達;同樣,對於長度為1,到達位置為(2,0)時,也一定無法到達。由此可推知,若奇偶性不同,則一定無法到達指定位置
在除去這兩種情況下,剩餘的情況都一定有答案。鑑於其可能解時連續的整數,因此,可以用二分列舉所有可能,進而找出最小的連續區間長度。 應注意,當根據給定字串移動就能到達指定位置,即最小區間為0時,應排除在二分列舉的情況之外。 當列舉長度為 x 時,考慮在 string 中所有長度為 x 的子串,是否存在一個子串可行。若存在,嘗試縮短子串長度;若不存在,延長子串長度。
判斷子串是否可行的方法: 設全集為給定字串,沿著子串的補集移動,記這樣移動到的點為 pos 。求 pos 到 指定位置 的距離,記為 d ,記子串的長度為 len。滿足如下兩種情況,則子串可行
- d < len
- d%2==len%2
詳細說明見上
其次,考慮二分結束時,程式的輸出,對於標記 inf ,sup 有兩種可能
- inf == sup 此時輸出inf 或 sup 均可
- inf+1 == sup 此時考慮如果進行下一次迴圈, 若fessible(mid) 為 true,sup=mid && mid==inf ,輸出inf 或 sup均可 若fessible(mid) 為 false,說明最小區間長度為 inf 時不可行,故應輸出sup
綜上所述,應輸出 sup
#include <iostream>
#include <climits>
#include <algorithm>
#include <utility>
#include <string>
#include <map>
#define rep(intdex,star,finish) for(int index=star;index<finish;index++)
#define drep(index,finish,star) for(int index=finish;index>=star;index--)
#define Pair pair<int,int>
#define Make(first,second) make_pair(first,second)
#define re return
using namespace std;
int len;
string step;
Pair aim; //first X second Y
inline int abs(int x);
inline int getDis(Pair &a,Pair &b);
inline bool check(int len,Pair &pos,Pair &aim);
inline void shift(Pair &pos,char direction,int addOrcancel);
bool fessible(int n);
int main(){
ios::sync_with_stdio(false);
cin>>len;
cin>>step;
cin>>aim.first>>aim.second;
Pair ini=Make(0,0);
if(!check(len,ini,aim)){
cout<<"-1"<<endl;
re 0;
}
for(int i=0;i<len;i++)
shift(ini,step[i],1);
if(ini.first==aim.first && ini.second==aim.second){
cout<<"0"<<endl;
re 0;
}
int inf=0,sup=len;
while(inf+1<sup){
int mid=inf+(sup-inf)/2;
if(fessible(mid))
sup=mid;
else
inf=mid;
}
cout<<sup<<endl;
re 0;
}
inline int abs(int x){
if(x<0)
re -x;
re x;
}
inline int getDis(Pair &a,Pair &b){
re abs(a.first-b.first)+abs(a.second-b.second);
}
inline bool check(int len,Pair &pos,Pair &aim){
int d=getDis(pos,aim);
if(len<d || d%2!=len%2)
re false;
re true;
}
void shift(Pair &pos,char direction,int addOrcancel){
switch(direction){
case 'U':
pos.second+=addOrcancel;
break;
case 'D':
pos.second-=addOrcancel;
break;
case 'L':
pos.first-=addOrcancel;
break;
case 'R':
pos.first+=addOrcancel;
break;
}
}
bool fessible(int n){
Pair pos=Make(0,0);
for(int i=n;i<len;i++)
shift(pos,step[i],1);
if(check(n,pos,aim))
re true;
int left=0,right=n;
while(right<len){
shift(pos,step[left],1);
shift(pos,step[right],-1);
if(check(n,pos,aim))
re true;
left++;
right++;
}
re false;
}