一.题目描述
NC564牛牛打怪兽
现在牛牛面前有n只怪兽,第i只怪兽的血量为ai。牛牛可以使用这个组合拳打第X怪兽,同时会打到第2X、2X+1这两个怪兽,每次组合拳会扣打到的怪兽一滴血。一个怪兽血量为0即为死亡,同时组合拳是可以鞭尸的,这意味着即使怪兽死亡,也可以对其使用组合拳。值得注意的是组合拳必须攻击三只怪兽。牛牛想知道它需要使用最少多少次组合拳才能把所有怪兽打死,如果打不死请输出-1。
二.算法(模拟)
首先我们要意识到组合拳是一次性可以打三只怪兽,并且打第X怪兽的时候,同时会打到第2X、2X+1这两个怪兽,每次组合拳会扣打到的怪兽一滴血,也就是说只有怪兽的数目是奇数的时候(而且数量大于2)才可以把所有怪兽打死,对于可以打死所有怪兽的情况,我们只需要利用数组进行模拟就行了,下面是完整代码:
class Solution {
public:
int slove(int n, vector<int>& A) {
//特判断 无法将所有的怪兽消灭的怪兽数目
if(n<=2||(n%2==0)){
return -1;
}
//记录需要打的组合数数目
int ans=0;
for(int i=n/2-1;i>=0;i--){
//下标是从0开始的 所以是2*i+1和2*i+2
int a=max(A[2*i+2],A[2*i+1]);
//要是怪兽已经死了 直接为0
A[i]=max(A[i]-a,0);
ans+=a;
}
//这块要注意最后一个怪兽要对其施加A[0]次组合拳
return ans+A[0];
}
};时间复杂度: 只需要对数组进行一次遍历
空间复杂度: 不需要额外空间
优缺点:时间复杂度低,代码简单便于实现。
三.算法(利用java实现)
利用java同样可以实现下面是完整代码:
import java.util.*;
public class Solution {
public int slove (int n, int[] A) {
//特判断 无法将所有的怪兽消灭的怪兽数目
if(n<=2||(n%2==0)){
return -1;
}
//记录需要打的组合数数目
int ans=0;
for(int i=n/2-1;i>=0;i--){
//下标是从0开始的 所以是2*i+1和2*i+2
//利用Math类判断大小
int a=Math.max(A[2*i+2],A[2*i+1]);
//要是怪兽已经死了 直接为0
A[i]=Math.max(A[i]-a,0);
ans+=a;
}
//这块要注意最后一个怪兽要对其施加A[0]次组合拳
return ans+A[0];
}
}时间复杂度: 只需要对数组的一半进行一次遍历
空间复杂度: 不需要额外空间来存储数据
优缺点:时间复杂度低,代码简单和c++一样便于实现。

京公网安备 11010502036488号