CodeForces 1073C Vasya and Robot_二分法

CodeForces 1073C Vasya and Robot

在平面直角坐标系中,一个机器人处于(0,0)点。它能进行以下的移动操作。 U 从(x,y)移动到(x,y+1); D 从(x,y)移动到(x,y-1); L 从(x,y)移动到(x-1,y); R 从(x,y)移动到(x+1,y). 现在有一个长度为n的操作序列。Vasya想修改这个序列使机器人最终移动到(x,y)。其修改的花费为maxID-minID+1。maxID是修改的操作的下标的最大值,minID是修改的操作的下标的最小值。如果没有修改,则花费为0。

Input

第一行一个整数,为n (1≤n≤2×10^5). 第二行一个长度为n的字符串,表示原来的操作序列。 第三行两个整数,为x,y。

Output

共一行,如果最后能够移动到(x,y),输出最小的花费,否则,输出−1。

Examples

Input
5
RURUU
-2 3
Output
3
Input
4
RULR
1 1
Output
0
Input
3
UUU
100 100
Output
-1

Note第一个样例中将序列改成LULUU。
第二个样例中,序列不用改变。
第三个样例中,无论如何修改都无法到达(x,y)

 

思路:

二分法求长度,

判断修改此长度的串能否达到终点

能的话r-1

不能l+1

 

具体实现判断过程:

只要横向移动为x,纵向移动为y就能刚好到达终点。很明显如果步数奇偶性和x+y的奇偶性不同的话肯定无法刚好到达终点。

遍历字符串,cx[i],cy[i]为走到i时的横纵移动量,递推建立前缀和数组。先将前一个cx,cy赋值给当前,判断当前字符Up cy+1 Down cy-1 Right cx+1 Left cx-1

然后判断时,将该长度在字符串上从左向右滑动,只计算除这段之外的横纵移动量(用前缀和数组直接查询),然后距离(x,y)的横绝对值+纵绝对值 如果小于等于长度,说明能刚好到达终点。

 

AC代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cmath>
 5 #define ll long long
 6 using namespace std;
 7 
 8 const int N = 1e6;
 9 char s[N];
10 int cx[N],cy[N];
11 int n,x,y;
12 int cost;
13 
14 bool isok(int len)
15 {
16     for(int i = 1; i <= n; ++i)
17     {
18         if(i+len-1 > n) return 0;
19         int x0 = cx[i-1]-cx[0], y0 = cy[i-1]-cy[0];
20         x0 += cx[n]-cx[i+len-1];
21         y0 += cy[n]-cy[i+len-1];
22         int temp = abs(x-x0)+abs(y-y0);
23         if(temp <= len)
24             return 1;
25     }
26     return 0;
27 }
28 
29 int main()
30 {
31 #ifdef local
32     freopen("in.txt","r",stdin);
33 #endif // local
34     cin >> n >> s >> x >> y;
35     int tmp = abs(x) + abs(y);
36     if(tmp > n || (n&1) != (tmp&1))
37         puts("-1");
38     else
39     {
40         for(int i = 1; i <= n; ++i)
41         {
42             cx[i] = cx[i-1];
43             cy[i] = cy[i-1];
44             int idx = i-1;
45             if(s[idx] == 'U') cy[i]++;
46             if(s[idx] == 'D') cy[i]--;
47             if(s[idx] == 'L') cx[i]--;
48             if(s[idx] == 'R') cx[i]++;
49         }
50         int l = 0, r = n;
51         int ans = -1;
52         while(l <= r)
53         {
54             int mid = (l+r)/2;
55             if(isok(mid))
56             {
57                 ans = mid;
58                 r = mid-1;
59             }
60             else
61             {
62                 l = mid+1;
63             }
64         }
65         cout << ans;
66     }
67     return 0;
68 }
View Code

 

posted @ 2019-01-19 22:36  shiyanini  阅读(220)  评论(0编辑  收藏  举报