机器人移动

机器人移动

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

初始时,机器人位于点 (0,0)

机器人可以执行四种行动指令:

  • U  — 从 (x,y) 移动到 (x,y+1)
  • D — 从 (x,y) 移动到 (x,y1)
  • L — 从 (x,y) 移动到 (x1,y)
  • R — 从 (x,y) 移动到 (x+1,y)

给定一个长度为 n 的指令序列,指令编号 1n,机器人将按顺序依次执行序列中的每个行动指令。

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

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

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

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

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

我们定义修改成本为 maxIDminID+1

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

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

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

输入格式

第一行包含整数 n

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

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

输出格式

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

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

数据范围

前四个测试点满足 1n10
所有测试点满足 1n2×105109x,y109

输入样例1:

5
RURUU
-2 3

输出样例1:

3

输入样例2:

4
RULR
1 1

输出样例2:

0

输入样例3:

3
UUU
100 100

输出样例3:

-1

 

解题思路

  这题是用二分来枚举答案。首先看看答案是否满足二段性。如果有最小的代价ans,那么可以发现如果代价大于ans,那么机器人也一定可以移动到终点(把区间长度取大些,用区间内的某个字符与端点进行交换)。如果代价小于ans,那么机器人不可以移动到终点。因此答案具有二段性。

  我们二分所需要的代价,假设为len,那么我们在check的时候,如果代价最多为len,意味着所有的操作指令一定在长度为len的区间内的,因此我们需要枚举序列中所有长度为len的区间。在枚举每一个长度为len的区间时,我们需要快速判断如果只修改这个区间内的指令,能否让机器人走到终点,这个时间复杂度应该是O(1)

  我们可以把整个序列分成三段:

  机器人每次都有上下左右四个方向的向量之一,如果要走到的最终位置,就是每一次指令对应的向量的和。其中,左右为同一个向量维度(水平方向),向左就减1,向右就加1。上下为同一个维度(竖直方向),向上就加1,向下就减1。 

  能不能到终点其实就是算这三段的向量和(分别算水平方向与竖直方向的)。由于我们只改变长度为len的这一段,另外两段是不会改变的,因此s1+s3是一个定值。然后长度为len的区间每一个位置都可以设置为任意的指令,因此s2是一个变量。因此s1+s2+s3得到的值应该是一个区间范围,我们只需要判断在这个区间范围内,是否包含到终点的值。

  要求某部分区间的和,可以用前缀和。不过这里需要开两个前缀和数组,分别求水平方向和竖直方向的前缀和。

  由于s1+s3是定值,因此我们先从起点根据这个和走到某一个点(x1,y1)。假设终点是(x2,y2),我们要从(x1,y1)走到(x2,y2),只能借助长度为len这个区间的指令。因此我们要判断的是从(x1,y1)能否恰好走len步,走到(x2,y2)

  由于求的是曼哈顿距离,因此要从(x1,y1)(x2,y2)的曼哈顿距离为|x2x1|+|y2y1|,即至少需要走|x2x1|+|y2y1|步。因为每走一步最多让这两点的距离减1,要让距离变成0,因此len要满足len|x2x1|+|y2y1|。因此我们可以构造出一条路径,使得恰好走|x2x1|+|y2y1|步,从(x1,y1)走到(x2,y2)。对于剩余的步数len|x2x1||y2y1|,这个值应该是偶数,因为此时(x1,y1)(x2,y2)的距离为0,如果是奇数,那么必然会使(x1,y1)(x2,y2)的距离变成11。偶数的话可以构造出11的情况,使得距离恰好抵消。

  因此判断能否通过这个长度len的区间,使得(x1,y1)走到(x2,y2),要满足两个条件:

  1. len|x2x1|+|y2y1|
  2. 2(len|x2x1|+|y2y1|)

  AC代码如下:

复制代码
 1 #include <cstdio>
 2 #include <cmath>
 3 #include <algorithm>
 4 using namespace std;
 5 
 6 const int N = 2e5 + 10;
 7 
 8 int n, x, y;
 9 char str[N];
10 int sx[N], sy[N];
11 
12 bool check(int len) {
13     for (int i = 1; i + len - 1 <= n; i++) {
14         int j = i + len - 1;
15         int xx = sx[n] - (sx[j] - sx[i - 1]), yy = sy[n] - (sy[j] - sy[i - 1]); // 相当于求s1和s3两个区间的和
16         if (abs(x - xx) + abs(y - yy) <= len && (len - abs(x - xx) - abs(y - yy)) % 2 == 0) return true;
17     }
18     
19     return false;
20 }
21 
22 int main() {
23     scanf("%d %s %d %d", &n, str + 1, &x, &y);
24     
25     if (abs(x - y) > n || (n - x - y) % 2) {
26         printf("-1");
27         return 0;
28     }
29     
30     for (int i = 1; i <= n; i++) {
31         sx[i] = sx[i - 1], sy[i] = sy[i - 1];
32         if (str[i] == 'U') sy[i]++;
33         else if (str[i] == 'D') sy[i]--;
34         else if (str[i] == 'L') sx[i]--;
35         else sx[i]++;
36     }
37     
38     int l = 0, r = n;
39     while (l < r) {
40         int mid = l + r >> 1;
41         if (check(mid)) r = mid;
42         else l = mid + 1;
43     }
44     
45     printf("%d", l);
46     
47     return 0;
48 }
复制代码

 

参考资料

  AcWing 4217. 机器人移动(AcWing杯 - 周赛):https://www.acwing.com/video/3692/

posted @   onlyblues  阅读(340)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
历史上的今天:
2021-04-01 在堆区申请二维数组的方法
Web Analytics
点击右上角即可分享
微信分享提示