Minimum possible final health of the last monster in a game - GeeksforGeeks

05 Aug, 2021
Given N monsters, each monster has initial health h[i] which is an integer. A monster is alive if its health is greater than 0. In each turn a random monster kills another random monster, the monster which is attacked, its health reduces by the amount of health of the attacking monster. This process is continued until a single monster is left. What will be the minimum possible health of the last remained monster. In others words, the task is to play the game in such a way that monster which is left in the end has the least possible health.Examples:  
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: 1Input: h[] = {5, 5, 5} Output: 5  
 
Approach: It can be observed from the problem that one has to find a certain value of health of the monster, let’s say k which can kill other monsters including self. Once this crucial observation is made problem becomes easy. Suppose we have two monsters with health h1 and h2, and let’s say h2 > h1. We can see that in a random choice, the optimal way would be to pick a monster with lower health and reduce the health of the other monster till its health becomes less than the health of the attacking monster. After that we will pick the second monster whose health has became less than h1 and the process will continue till only one monster is left. So at last we will be left with the minimum value which would be gcd(h1, h2). This gcd method can be extended for all the monsters. So our resultant minimum possible health of the monster will be the gcd of all the health of given monsters i.e. H(min) = gcd(h1, h2, ..., hn).Below is the implementation of the above approach:  
C++
Java
Python3
C#
PHP
Javascript
// C++ implementation of the approach#include <bits/stdc++.h>using namespace std; // Function to return the gcd of two numbersint gcd(int a, int b){    if (a == 0)        return b;    return gcd(b % a, a);} // Function to return the minimum// possible health for the monsterint 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 codeint main(){    int health[] = { 4, 6, 8, 12 };    int n = sizeof(health) / sizeof(health[0]);    cout << solve(health, n);     return 0;}
// Java implementation of the approachimport java.util.*; class GFG{ // Function to return the gcd of two numbersstatic 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 monsterstatic 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 codepublic 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 implementation of the approach # Function to return the gcd of two numbersdef gcd(a, b):     if (a == 0):        return b    return gcd(b % a, a) # Function to return the minimum# possible health for the monsterdef 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 codehealth = [4, 6, 8, 12]n = len(health)print(solve(health, n)) # This code is contributed by mohit kumar
// C# implementation of the approachusing System; class GFG{ // Function to return the gcd of two numbersstatic 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 monsterstatic 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 codepublic 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// PHP implementation of the approach // Function to return the gcd of two numbersfunction gcd($a, $b){    if ($a == 0)        return $b;    return gcd($b % $a, $a);} // Function to return the minimum// possible health for the monsterfunction solve($health, $n){    // gcd of first and second element    $currentgcd = gcd($health[0],                      $health[1]);     // gcd for all subsequent elements    for ($i = 2; $i < $n; ++$i)    {        $currentgcd = gcd($currentgcd,                          $health[$i]);    }    return $currentgcd;} // Driver code$health = array(4, 6, 8, 12);$n = sizeof($health);echo solve($health, $n); // This code is contributed by Akanksha Rai?>
<script> // Javascript implementation of the approach // Function to return the gcd of two numbersfunction gcd(a, b){    if (a == 0)        return b;    return gcd(b % a, a);}   // Function to return the minimum// possible health for the monsterfunction solve(health, n){    // gcd of first and second element    let currentgcd = gcd(health[0], health[1]);       // gcd for all subsequent elements    for (let i = 2; i < n; ++i)    {        currentgcd = gcd(currentgcd, health[i]);    }    return currentgcd;}       // Driver Code        let health = [ 4, 6, 8, 12 ];    let n = health.length;    document.write(solve(health, n));       // This code is contributed by target_2.</script>
2
 
Time Complexity: O(N * log(MAX)) where N is the size of the array and MAX is the maximum number in the array. We are running a loop that takes O(N) time. Also, the GCD function takes O(log(min(A, B)), and in the worst case when A and B are the same and A = B = MAX then the GCD function takes O(log(MAX)) time. So, overall time complexity = O(N * log(MAX))Auxiliary Space: O(log(MAX))
mohit kumar 29
SURENDRA_GANGWAR
Akanksha_Rai
andrew1234
target_2
pankajsharmagfg
GCD-LCM
HCF
Algorithms
Greedy
Mathematical
Greedy
Mathematical
Algorithms
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
SDE SHEET - A Complete Guide for SDE Preparation
DSA Sheet by Love Babbar
How to write a Pseudo Code?
Understanding Time Complexity with Simple Examples
Introduction to Algorithms
Dijkstra's shortest path algorithm | Greedy Algo-7
Prim’s Minimum Spanning Tree (MST) | Greedy Algo-5
Kruskal’s Minimum Spanning Tree Algorithm | Greedy Algo-2
Program for array rotation
Write a program to print all permutations of a given string