给定N 个怪物,每个怪物的初始生命值h[i]是一个整数。如果怪物的生命值大于0则它是活着的。每回合一个随机怪物杀死另一个随机怪物,被攻击的怪物,其生命值减少攻击怪物的生命值。这个过程一直持续到只剩下一个怪物为止。最后剩下的怪物的最低生命值是多少。换句话说,任务是以这样一种方式玩游戏,即最后留下的怪物的生命值尽可能低。
例子:
Input: h[] = {2, 14, 28, 56}
Output: 2
When only the first monster keeps on attacking the remaining 3 monsters, the final health of the last monster will be 2, which is minimum.
Input: h[] = {7, 17, 9, 100, 25}
Output: 1
Input: h[] = {5, 5, 5}
Output: 5
方法:从这个问题可以看出,一个人必须找到一个怪物的健康值,假设k可以杀死包括自己在内的其他怪物。一旦进行了这个关键的观察,问题就变得容易了。假设我们有两个生命值为 h1和h2 的怪物,假设h2 > h1 。我们可以看到,在随机选择中,最佳方式是选择一个生命值较低的怪物并降低另一个怪物的生命值,直到其生命值低于攻击怪物的生命值。之后,我们将选择第二个生命值低于h1 的怪物,这个过程将继续直到只剩下一个怪物。所以最后我们将得到最小值,即gcd(h1, h2) 。这个 gcd 方法可以扩展到所有怪物。
所以我们得到的怪物的最小可能健康将是给定怪物的所有健康的 gcd,即 H(min) = gcd(h1, h2, …, hn)。
下面是上述方法的实现:
C++
// C++ implementation of the approach
#include
using namespace std;
// Function to return the gcd of two numbers
int gcd(int a, int b)
{
if (a == 0)
return b;
return gcd(b % a, a);
}
// Function to return the minimum
// possible health for the monster
int solve(int* health, int n)
{
// gcd of first and second element
int currentgcd = gcd(health[0], health[1]);
// gcd for all subsequent elements
for (int i = 2; i < n; ++i) {
currentgcd = gcd(currentgcd, health[i]);
}
return currentgcd;
}
// Driver code
int main()
{
int health[] = { 4, 6, 8, 12 };
int n = sizeof(health) / sizeof(health[0]);
cout << solve(health, n);
return 0;
}
Java
// Java implementation of the approach
import java.util.*;
class GFG
{
// Function to return the gcd of two numbers
static int gcd(int a, int b)
{
if (a == 0)
return b;
return gcd(b % a, a);
}
// Function to return the minimum
// possible health for the monster
static int solve(int health[], int n)
{
// gcd of first and second element
int currentgcd = gcd(health[0], health[1]);
// gcd for all subsequent elements
for (int i = 2; i < n; ++i)
{
currentgcd = gcd(currentgcd, health[i]);
}
return currentgcd;
}
// Driver code
public static void main(String args[])
{
int health[] = { 4, 6, 8, 12 };
int n = health.length;
System.out.println(solve(health, n));
}
}
// This code is contributed by
// Surendra_Gangwar
Python3
# Python3 implementation of the approach
# Function to return the gcd of two numbers
def gcd(a, b):
if (a == 0):
return b
return gcd(b % a, a)
# Function to return the minimum
# possible health for the monster
def solve(health, n):
# gcd of first and second element
currentgcd = gcd(health[0], health[1])
# gcd for all subsequent elements
for i in range(2, n):
currentgcd = gcd(currentgcd,
health[i])
return currentgcd
# Driver code
health = [4, 6, 8, 12]
n = len(health)
print(solve(health, n))
# This code is contributed by mohit kumar
C#
// C# implementation of the approach
using System;
class GFG
{
// Function to return the gcd of two numbers
static int gcd(int a, int b)
{
if (a == 0)
return b;
return gcd(b % a, a);
}
// Function to return the minimum
// possible health for the monster
static int solve(int []health, int n)
{
// gcd of first and second element
int currentgcd = gcd(health[0], health[1]);
// gcd for all subsequent elements
for (int i = 2; i < n; ++i)
{
currentgcd = gcd(currentgcd, health[i]);
}
return currentgcd;
}
// Driver code
public static void Main(String []args)
{
int []health = { 4, 6, 8, 12 };
int n = health.Length;
Console.WriteLine(solve(health, n));
}
}
// This code is contributed by Arnab Kundu
PHP
Javascript
2
时间复杂度: O(N * log(MAX)),其中 N 是数组的大小,MAX 是数组中的最大数量。
我们正在运行一个需要 O(N) 时间的循环。此外,GCD函数需要 O(log(min(A, B)),在最坏的情况下,当 A 和 B 相同且 A = B = MAX 时,GCD函数需要 O(log(MAX)) 时间。所以,总时间复杂度 = O(N * log(MAX))
辅助空间: O(log(MAX))
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。