2069. 模拟行走机器人 II

This commit is contained in:
li_chx 2026-04-07 09:23:00 +08:00
parent 98eafcac0e
commit 8cc2ab780c
Signed by: li_chx
GPG Key ID: C7CF27EFA1E58BAC
1 changed files with 97 additions and 69 deletions

View File

@ -1,75 +1,103 @@
use std::cmp::{max, min};
use std::mem::swap;
use crate::arr::make_matrix;
struct Solution;
mod arr;
impl Solution {
pub fn max_walls(robots: Vec<i32>, distance: Vec<i32>, walls: Vec<i32>) -> i32 {
let mut walls = walls;
let mut rd = robots
.iter()
.zip(distance.iter())
.collect::<Vec<(&i32, &i32)>>();
rd.sort_unstable_by(|a, b| a.0.cmp(b.0));
walls.sort_unstable();
let mut dp = vec![vec![0; 2]; 2];
let (mut lastrr, mut last_robot) = (0, 0);
let (mut x,mut y) = (0, 1);
for i in 0..rd.len() {
let (robot, dis) = rd[i];
// 第一个能打到的
let ll_theory = walls.partition_point(|&v| *robot - *dis > v);
// 第一个打不到的
let lr_theory = walls.partition_point(|&v| *robot >= v);
// 第一个能打到的
let rl_theory = walls.partition_point(|&v| *robot > v);
// 第一个打不到的
let rr_theory = walls.partition_point(|&v| *robot + *dis >= v);
// 因bot阻挡 最后一个打不到的
let robot_l_idx = last_robot;
let robot_r_idx = if i != rd.len() - 1 {
walls.partition_point(|&v| *rd[i + 1].0 > v)
} else {
rr_theory
};
dp[y][0] = max(
dp[x][0] + lr_theory - max(ll_theory, robot_l_idx),
dp[x][1] + max(0, lr_theory - max(ll_theory, lastrr)),
);
dp[y][1] = max(dp[x][0], dp[x][1])
+ max(
0,
max(
min(rr_theory, max(robot_r_idx as i32, 0) as usize) as i32
- rl_theory as i32,
0,
) as usize,
);
lastrr = min(rr_theory, robot_r_idx);
last_robot = lr_theory;
swap(&mut x, &mut y);
struct Robot {
a: i32,
b: i32,
c: i32,
d: i32,
width: i32,
height: i32,
length: i32,
no_step: bool,
current: i32,
}
/**
* `&self` means the method takes an immutable reference.
* If you need a mutable reference, change it to `&mut self` instead.
*/
impl Robot {
fn new(width: i32, height: i32) -> Self {
Robot {
a: 0,
b: height - 1,
c: height + width - 2,
d: height * 2 + width - 3,
width,
height,
length: width * 2 + height * 2 - 4,
no_step: true,
current: height - 1,
}
max(dp[x][0], dp[x][1]) as i32
}
fn step(&mut self, num: i32) {
self.no_step = false;
self.current = (self.current + num) % self.length;
}
fn get_pos(&self) -> Vec<i32> {
if self.no_step {
return vec![0, 0];
}
if self.current > self.d {
return vec![self.width - (self.current - self.d) - 1, self.height - 1];
}
if self.current > self.c {
return vec![self.width - 1, self.current - self.c];
}
if self.current > self.b {
return vec![self.current - self.b, 0];
}
vec![0, self.height - 1 - self.current]
}
fn get_dir(&self) -> String {
if self.no_step {
return "East".to_string();
}
if self.current > self.d || self.current == 0 {
return "West".to_string();
}
if self.current > self.c {
return "North".to_string();
}
if self.current > self.b {
return "East".to_string();
}
"South".to_string()
}
}
fn main() {
let result = Solution::max_walls(
vec![
63, 56, 40, 45, 4, 9, 44, 69, 55, 26, 73, 15, 12, 60, 43, 39, 37, 74, 36, 34, 13, 23,
66, 14, 11, 42, 72, 3, 57, 10, 53, 8, 70, 17, 58, 61, 30, 32,
],
vec![
8, 7, 4, 8, 9, 5, 2, 4, 5, 2, 6, 9, 5, 9, 5, 3, 7, 6, 9, 2, 8, 7, 4, 3, 5, 1, 7, 5, 1,
3, 5, 3, 5, 4, 8, 7, 6, 4,
],
vec![6, 22, 50, 52, 20, 9, 23, 75, 26, 21, 60, 58, 41, 28, 30],
);
println!("{:?}", result);
}
/*
[(3, 5), (4, 9), (8, 3), (9, 5), (10, 3), (11, 5), (12, 5), (13, 8), (14, 3), (15, 9), (17, 4), (23, 7), (26, 2), (30, 6), (32, 4), (34, 2), (36, 9), (37, 7), (39, 3), (40, 4), (42, 1), (43, 5), (44, 2), (45, 8), (53, 5), (55, 5), (56, 7), (57, 1), (58, 8), (60, 9), (61, 7), (63, 8), (66, 4), (69, 4), (70, 5), (72, 7), (73, 6), (74, 6)]
[6, 9, 20, 21, 22, 23, 26, 28, 30, 41, 50, 52, 58, 60, 75]
r6 l6 r6 l9 r9 l9 r21 l23 r23 l26 r28 l30 r30 l30 r41 l41 r41 l41 r52 l52 r52 l58 r58 l60 r60 l60 r75
[0, 0], [0, 1], [1, 1], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 4], [6, 5], [7, 8], [9, 9], [9, 9], [9, 9], [9, 9], [9, 9], [9, 9], [9, 10], [10, 10], [10, 10], [10, 10], [10, 12], [12, 12], [12, 12], [12, 12], [12, 12], [13, 13], [14, 14], [14, 14], [14, 14], [14, 14], [14, 14], [14, 14], [14, 14], [14, 14], [14, 15]]
14
/**
* Your Robot object will be instantiated and called as such:
* let obj = Robot::new(width, height);
* obj.step(num);
* let ret_2: Vec<i32> = obj.get_pos();
* let ret_3: String = obj.get_dir();
*/
fn main() {
let opers = vec![
"Robot", "step", "step", "getPos", "getDir", "step", "step", "step", "getPos", "getDir",
];
let data = make_matrix(" [[20, 13], [50], [0], [], [], [2], [1], [4], [], []]");
let mut robot = Robot::new(data[0][0], data[0][1]);
for i in 0..opers.len() {
let oper = opers[i];
println!("{:#?}", oper);
match oper {
"step" => {
robot.step(data[i][0]);
}
"getPos" => {
println!("{:#?}", robot.get_pos());
}
"getDir" => {
println!("{:#?}", robot.get_dir());
}
_ => {}
}
}
}