You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
8.5 KiB
8.5 KiB
2383. 赢得比赛需要的最少训练时长
description:
你正在参加一场比赛,给你两个 正 整数 initialEnergy
和 initialExperience
分别表示你的初始精力和初始经验。另给你两个下标从 0 开始的整数数组 energy
和 experience
,长度均为 n
。你将会 依次 对上 n
个对手。第 i
个对手的精力和经验分别用 energy[i]
和 experience[i]
表示。当你对上对手时,需要在经验和精力上都 严格 超过对手才能击败他们,然后在可能的情况下继续对上下一个对手。击败第 i
个对手会使你的经验 增加 experience[i]
,但会将你的精力 减少 energy[i]
。在开始比赛前,你可以训练几个小时。每训练一个小时,你可以选择将增加经验增加 1 或者 将精力增加 1 。返回击败全部 n
个对手需要训练的 最少 小时数目。
代码:
fn main() {
let (mut initial_energy, mut initial_experience) = (1, 1);
let energy:Vec<i32> = vec![1,1,1,1];
let experience:Vec<i32> = vec![1,1,1,50];
let res = min_number_of_hours(initial_energy, initial_experience, &energy, &experience);
println!("res is: {}", res);
let a:&Vec<i32> = &experience;
// &i 相当于 &i32, 故i为i32;
for &i in a{
if i < 2{
println!(" i < 2 is: {}", i + 2);
}else {
println!("i is: {}", i);
}
}
for i in a{
if *i < 2{
println!(" i < 2 is: {}", i + 2);
}else {
println!("i is: {}", i);
}
}
let a:&i32 = &5;
println!("{}", a + 3); // ok,会自动解引用
// println!("{}", a > 3); // error
}
fn min_number_of_hours(initial_energy:i32, mut initial_experience:i32, energy:&Vec<i32>, experience:&Vec<i32>) -> i32{
// let mut sum = 0;
// for i in energy{
// sum += i;
// }
// 与上面代码效果一样
let sum = energy.iter().sum();
let mut training_hours = if initial_energy > sum {0} else { sum - initial_energy + 1 };
for &i in experience{
if initial_experience > i{
initial_experience += i;
}else {
training_hours += i - initial_experience + 1;
initial_experience = 2 * i + 1;
}
}
// 如果是 experience:Vec<i32> 这样没问题,但experience:&Vec<i32>这样写得话,下面i需要*i来进行if,因为&i32在if时不会自动解引用。
// for i in experience{
// if initial_experience > *i{
// initial_experience += i;
// }else {
// training_hours += i - initial_experience + 1;
// initial_experience = 2 * i + 1;
// }
// }
training_hours
}
图:
修改函数参数,使用&[i32]替代Vec
fn main() {
let (mut initial_energy, mut initial_experience) = (1, 1);
let energy:Vec<i32> = vec![1,1,1,1];
let experience:Vec<i32> = vec![1,1,1,50];
let res = min_number_of_hours(initial_energy, initial_experience, &energy, &experience);
println!("res is: {}", res);
let a:&Vec<i32> = &experience;
for i in a{
if *i < 2{
println!(" i < 2 is: {}", i + 2);
}else {
println!("i > 2 is: {}", i);
}
}
// &i 相当于 &i32, 故i为i32;
for &i in a{
if i < 2{
println!(" i < 2 is: {}", i + 2);
}else {
println!("i > 2 is: {}", i);
}
}
let a:&i32 = &5;
println!("{}", a + 3); // ok,会自动解引用
// println!("{}", a > 3); // error
}
fn min_number_of_hours(initial_energy:i32, mut initial_experience:i32, energy:&[i32], experience:&[i32]) -> i32{
let sum = energy.iter().sum();
println!("sum : {}", sum);
let mut training_hours = if initial_energy > sum {0} else { sum - initial_energy + 1 };
for &i in experience{
if initial_experience > i{
initial_experience += i;
}else {
training_hours += i - initial_experience + 1;
initial_experience = 2 * i + 1;
}
}
println!("capital : {}", experience.len());
training_hours
}
fn min_number_of_hours2(initial_energy:i32, mut initial_experience:i32, energy:&Vec<i32>, experience:&Vec<i32>) -> i32{
// let mut sum = 0;
// for i in energy{
// sum += i;
// }
// 与上面代码效果一样
let sum = energy.iter().sum();
println!("sum : {}", sum);
let mut training_hours = if initial_energy > sum {0} else { sum - initial_energy + 1 };
for &i in experience{
if initial_experience > i{
initial_experience += i;
}else {
training_hours += i - initial_experience + 1;
initial_experience = 2 * i + 1;
}
}
// 如果是 experience:Vec<i32> 这样没问题,但experience:&Vec<i32>这样写得话,下面i需要*i来进行if,因为&i32在if时不会自动解引用。
// for i in experience{
// if initial_experience > *i{
// initial_experience += i;
// }else {
// training_hours += i - initial_experience + 1;
// initial_experience = 2 * i + 1;
// }
// }
println!("capital : {}", energy.capacity());
training_hours
}
区别:
- 使用
&[i32]
更高效。&Vec<i32>
包含了指向堆上分配的数组的指针,以及两个整数表示数组的长度和容量,而&[i32]
只包含一个指向堆上分配的数组的指针和一个整数表示数组的长度。因此,使用&[i32]
要比使用&Vec<i32>
更高效。 - 使用
&[i32]
更灵活。&[i32]
不仅可以接受Vec<i32>
的引用,还可以接受其他实现了AsRef<[i32]>
trait 的类型,包括数组和其他类型的 slice。这样,函数的参数类型就更加通用,更易于重用和组合。 - 使用
&Vec<i32>
可以访问Vec<i32>
的容量。在Vec<i32>
中,容量是在堆上分配的数组的大小。使用&Vec<i32>
作为函数参数,可以调用capacity()
方法访问这个容量值。如果你的函数需要访问这个容量值,那么使用&Vec<i32>
就更合适。
总之,除非需要访问 Vec<i32>
的容量,否则应该优先使用 &[i32]
作为函数参数类型。
c++:
#include <iostream>
#include <vector>
class Solution{
public:
int minNumberOfHours(int initialEnergy, int initialExperience, std::vector<int>& energy, std::vector<int>& experience) {
int sum = 0;
for (int e : energy) {
sum += e;
}
int trainingHours = initialEnergy > sum ? 0 : sum + 1 - initialEnergy;
for (int e : experience) {
if (initialExperience <= e) {
trainingHours += 1 + (e - initialExperience);
initialExperience = 2 * e + 1;
} else {
initialExperience += e;
}
}
return trainingHours;
}
int minNumberOfHours2(int initialEnergy, int initialExperience, std::vector<int>& energy, std::vector<int>& experience){
int sum = this->sum(energy);
int trainingHours = initialExperience > sum?0:sum-initialEnergy+1;
for(std::vector<int>::iterator it = experience.begin(); it != experience.end(); ++it){
if(initialExperience <= *it){
trainingHours += (*it - initialExperience)+1;
initialExperience = 2 * (*it) + 1;
} else{
initialExperience += *it;
}
}
return trainingHours;
}
private:
int sum(std::vector<int>& energy){
int sum = 0;
for (std::vector<int>::iterator it = energy.begin(); it != energy.end(); ++it)
{
sum += *it;
}
return sum;
}
};
int main() {
Solution *so = new Solution();
int initialEnergy = 1, initalExperience = 1;
std::vector<int> experience(4, 0);
// 两种赋值方式
std::vector<int> energy = {1, 1, 1, 1};
experience[0] = 1; experience[1] = 1; experience[2] = 1; experience[3] = 50;
int res = so->minNumberOfHours(initialEnergy, initalExperience, energy, experience);
std::cout << res << " ";
return 0;
}
图: