0%

4217.机器人移动

4217. 机器人移动

题目描述:

在一个无限大的二维平面上有一个机器人。

初始时,机器人位于点 $ (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 $ 的指令序列,指令编号 $ 1 \sim n $ ,机器人将按顺序依次执行序列中的每个行动指令。

我们希望机器人最终抵达目标地点 $ (a,b) $ 。

为了达成这一目的,我们可能需要对指令序列进行修改。

每次修改可以选择其中一个指令,并将其替换为四种指令之一。

注意,只能对序列中的指令进行替换,不得随意删除指令或添加额外指令。

不妨设经过修改的指令中,编号最小的指令编号为 minID,编号最大的指令编号为 maxID。

我们定义修改成本为 $ \text{maxID}−\text{minID}+1 $ 。

例如,将 RRRRRRR 修改为 RLRRLRL,则编号为 $ 2,5,7 $ 的指令经过了修改,修改成本为 $ 7−2+1=6 $ 。

请你计算,为了使得机器人能够最终抵达目标点 $ (a,b) $ ,所需花费的最小修改成本。

如果不需要对序列进行修改,则成本为 0。

输入格式

第一行包含整数 n。

第二行包含一个长度为 n 的字符串,表示指令序列,字符串中只包含 UDLR

第三行包含两个整数 a,b,表示机器人的目标位置为 $ (a,b) $ 。

输出格式

输出一个整数,表示最小修改成本。

如果无论如何修改,机器人都无法抵达目标位置,则输出 −1。

数据范围

前四个测试点满足 $ 1 \le n \le 10 $ 。
所有测试点满足 $ 1 \le n \le 2×10^5,−10^9 \le x,y \le 10^9 $ 。

输入样例1:

1
2
3
5
RURUU
-2 3

输出样例1:

1
3

输入样例2:

1
2
3
4
RULR
1 1

输出样例2:

1
0

输入样例3:

1
2
3
3
UUU
100 100

输出样例3:

1
-1

题解:

代价的定义为 $ \text{maxID}−\text{minID}+1 $ ,可以发现是一个区间 $ [minID, maxID] $ ,只需要对这个区间中的指令进行修改。显然满足二分性。二分区间的长度,枚举每一个区间,注意如何进行 check mid。

此外,把每次移动都看作向量的加减,那么只需要记录两个方向轴的单位向量就行。可以使用前缀和,得到 $ [0, minID - 1], [maxID + 1, n - 1] $ 里面的 $ x,y $ 方向的数量,和终点坐标就行对比,看看需要改变多少,记为 $ need $ ,需要满足 mid >= need,而且二者需要保持相同的奇偶性,因为相差为奇数时无法通过抵消满足。

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
using namespace std;
using namespace FAST_IO;
const ll mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const ll INF_LL = 0x3f3f3f3f3f3f3f3f;
const double eps = 1e-5;
const int maxn = 2e5 + 10;
const int maxm = 1e5 + 10;
int t, n, m, k;
// 看成 右 上
PII a[maxn];
string s;
int ex, ey;
bool check(int mid)
{
if (mid > n)
return false;
int sx, sy, need;
// 长度是 len
for (int i = 1; i <= n - mid + 1; i++)
{
// start = i, end = i + mid - 1
sx = a[i - 1].first + a[n].first - a[i + mid - 1].first;
sy = a[i - 1].second + a[n].second - a[i + mid - 1].second;
need = abs(sx - ex) + abs(sy - ey);
if (need <= mid && (mid - need) % 2 == 0)
{
return true;
}
}
return false;
}

int main()
{
// #define COMP_DATA
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n;
cin >> s;
cin >> ex >> ey;
for (int i = 1; i <= s.length(); i++)
{
a[i].first = a[i].second = 0;
if (s[i - 1] == 'R')
{
a[i].first = 1;
}
else if (s[i - 1] == 'L')
{
a[i].first = -1;
}
else if (s[i - 1] == 'U')
{
a[i].second = 1;
}
else
{
a[i].second = -1;
}
}
// 求个前缀和
for (int i = 1; i <= n; i++)
{
a[i].first += a[i - 1].first;
a[i].second += a[i - 1].second;
}
int l = 0, r = n;
int ans = -1;
while (l <= r)
{
int mid = (l + r) >> 1;
if (check(mid))
{
ans = mid;
r = mid - 1;
}
else
{
l = mid + 1;
}
}
cout << ans << endl;
return 0;
}