Given an array arr[] of size N, the task is to find the winner of the game when two players play the game optimally as per the following rules:
- Player 1 starts the game.
- In each turn, a player removes an element from the array.
- Player 2 will win the game only if GCD of all the elements removed by Player 1 becomes equal to 1.
Examples:
Input: arr[] = { 2, 4, 8 }
Output: Player 1
Explanation:
Turn 1: Player 1 removes arr[0]. Therefore, GCD of elements removed by Player 1 = 2
Turn 2: Since GCD of elements removed by Player 1 not equal to 1. Therefore, Player 2 removes arr[1].
Turn 3: Player 1 removes arr[2]. Therefore, GCD of elements removed by Player 1 = GCD(2, 8) = 2
Since the GCD of elements removed by player 1 is not equal to 1, Player 1 wins the game.Input: arr[] = { 2, 1, 1, 1, 1, 1 }
Output: Player 2
Turn 1: Player 1 removes arr[0]. Therefore, GCD of elements removed by Player 1 = 2
Turn 2: Since GCD of elements removed by Player 1 not equal to 1, Player 2 removes arr[1].
Turn 3: Player 1 removes arr[2]. Therefore, GCD of elements removed by Player 1 = GCD(2, 1) = 1
Since GCD of elements removed by player 1 is 1, Player 2 wins the game.
Approach: The optimal way for Player 1 and Player 2 is to always remove the array elements which have at least one common prime factor in most of the array elements. Follow the steps below to solve the problem:
- Initialize a Map, say mp, such that mp[i] stores the count of array elements whose prime factor is i
- Traverse the map and find the maximum value present in the Map, say maxCnt.
- If N is an odd number and maxCnt is equal to N or if N is an even number and maxCnt ? N – 1, then Player 1 wins the game.
- Otherwise, Player 2 wins the game.
Below is the implementation of the above approach:
// C++ program to implement // the above approach #include <bits/stdc++.h> using namespace std;
// Function to find the winner of the game by // removing array elements whose GCD is 1 void findWinnerGameRemoveGCD( int arr[], int n)
{ // mp[i]: Stores count of array
// elements whose prime factor is i
unordered_map< int , int > mp;
// Traverse the array
for ( int i = 0; i < n; i++) {
// Calculate the prime factors
// of arr[i]
for ( int j = 2; j * j <= arr[i];
j++) {
// If arr[i] is divisible by j
if (arr[i] % j == 0) {
// Update mp[j]
mp[j]++;
while (arr[i] % j == 0) {
// Update arr[i]
arr[i] = arr[i] / j;
}
}
}
// If arr[i] exceeds 1
if (arr[i] > 1) {
mp[arr[i]]++;
}
}
// Stores maximum value
// present in the Map
int maxCnt = 0;
// Traverse the map
for ( auto i : mp) {
// Update maxCnt
maxCnt = max(maxCnt,
i.second);
}
// If n is an even number
if (n % 2 == 0) {
// If maxCnt is greater
// than or equal to n-1
if (maxCnt >= n - 1) {
// Player 1 wins
cout << "Player 1" ;
}
else {
// Player 2 wins
cout << "Player 2" ;
}
}
else {
// If maxCnt equal to n
if (maxCnt == n) {
// Player 1 wins
cout << "Player 1" ;
}
else {
// Player 2 wins
cout << "Player 2" ;
}
}
} // Driver Code int main()
{ int arr[] = { 2, 4, 8 };
int N = sizeof (arr)
/ sizeof (arr[0]);
findWinnerGameRemoveGCD(arr, N);
return 0;
} |
// Java program to implement // the above approach import java.util.*;
class GFG{
// Function to find the winner of the game by
// removing array elements whose GCD is 1
static void findWinnerGameRemoveGCD( int arr[], int n)
{
// mp[i]: Stores count of array
// elements whose prime factor is i
HashMap<Integer,
Integer> mp = new HashMap<Integer,
Integer>();
// Traverse the array
for ( int i = 0 ; i < n; i++) {
// Calculate the prime factors
// of arr[i]
for ( int j = 2 ; j * j <= arr[i];
j++) {
// If arr[i] is divisible by j
if (arr[i] % j == 0 ) {
// Update mp[j]
if (mp.containsKey(j))
{
mp.put(j, mp.get(j) + 1 );
}
else
{
mp.put(j, 1 );
}
while (arr[i] % j == 0 ) {
// Update arr[i]
arr[i] = arr[i] / j;
}
}
}
// If arr[i] exceeds 1
if (arr[i] > 1 ) {
if (mp.containsKey(arr[i]))
{
mp.put(arr[i], mp.get(arr[i]) + 1 );
}
else
{
mp.put(arr[i], 1 );
}
}
}
// Stores maximum value
// present in the Map
int maxCnt = 0 ;
// Traverse the map
for (Map.Entry<Integer,
Integer> i : mp.entrySet()) {
// Update maxCnt
maxCnt = Math.max(maxCnt, i.getValue());
}
// If n is an even number
if (n % 2 == 0 ) {
// If maxCnt is greater
// than or equal to n-1
if (maxCnt >= n - 1 ) {
// Player 1 wins
System.out.print( "Player 1" );
}
else {
// Player 2 wins
System.out.print( "Player 2" );
}
}
else {
// If maxCnt equal to n
if (maxCnt == n) {
// Player 1 wins
System.out.print( "Player 1" );
}
else {
// Player 2 wins
System.out.print( "Player 2" );
}
}
}
// Driver code
public static void main(String[] args)
{
int arr[] = { 2 , 4 , 8 };
int N = arr.length;
findWinnerGameRemoveGCD(arr, N);
}
} // This code is contributed by susmitakundugoaldanga |
# Python3 program to implement # the above approach # Function to find the winner of the game by # removing array elements whose GCD is 1 def findWinnerGameRemoveGCD(arr, n) :
# mp[i]: Stores count of array
# elements whose prime factor is i
mp = dict .fromkeys(arr, 0 );
# Traverse the array
for i in range (n) :
# Calculate the prime factors
# of arr[i]
for j in range ( 2 , int (arr[i] * ( 1 / 2 )) + 1 ) :
# If arr[i] is divisible by j
if (arr[i] % j = = 0 ) :
# Update mp[j]
mp[j] + = 1 ;
while (arr[i] % j = = 0 ) :
# Update arr[i]
arr[i] = arr[i] / / j;
# If arr[i] exceeds 1
if (arr[i] > 1 ) :
mp[arr[i]] + = 1 ;
# Stores maximum value
# present in the Map
maxCnt = 0 ;
# Traverse the map
for i in mp:
# Update maxCnt
maxCnt = max (maxCnt,mp[i]);
# If n is an even number
if (n % 2 = = 0 ) :
# If maxCnt is greater
# than or equal to n-1
if (maxCnt > = n - 1 ) :
# Player 1 wins
print ( "Player 1" ,end = "");
else :
# Player 2 wins
print ( "Player 2" ,end = "");
else :
# If maxCnt equal to n
if (maxCnt = = n) :
# Player 1 wins
print ( "Player 1" ,end = "");
else :
# Player 2 wins
print ( "Player 2" ,end = "");
# Driver Code if __name__ = = "__main__" :
arr = [ 2 , 4 , 8 ];
N = len (arr);
findWinnerGameRemoveGCD(arr, N);
# This code is contributed by AnkThon
|
// C# program to implement // the above approach using System;
using System.Collections.Generic;
class GFG{
// Function to find the winner of the game by
// removing array elements whose GCD is 1
static void findWinnerGameRemoveGCD( int []arr, int n)
{
// mp[i]: Stores count of array
// elements whose prime factor is i
Dictionary< int ,
int > mp = new Dictionary< int ,
int >();
// Traverse the array
for ( int i = 0; i < n; i++) {
// Calculate the prime factors
// of arr[i]
for ( int j = 2; j * j <= arr[i];
j++) {
// If arr[i] is divisible by j
if (arr[i] % j == 0)
{
// Update mp[j]
if (mp.ContainsKey(j))
{
mp[j] = mp[j] + 1;
}
else
{
mp.Add(j, 1);
}
while (arr[i] % j == 0)
{
// Update arr[i]
arr[i] = arr[i] / j;
}
}
}
// If arr[i] exceeds 1
if (arr[i] > 1)
{
if (mp.ContainsKey(arr[i]))
{
mp[arr[i]] = mp[arr[i]] + 1;
}
else
{
mp.Add(arr[i], 1);
}
}
}
// Stores maximum value
// present in the Map
int maxCnt = 0;
// Traverse the map
foreach (KeyValuePair< int ,
int > i in mp)
{
// Update maxCnt
maxCnt = Math.Max(maxCnt, i.Value);
}
// If n is an even number
if (n % 2 == 0)
{
// If maxCnt is greater
// than or equal to n-1
if (maxCnt >= n - 1)
{
// Player 1 wins
Console.Write( "Player 1" );
}
else
{
// Player 2 wins
Console.Write( "Player 2" );
}
}
else
{
// If maxCnt equal to n
if (maxCnt == n)
{
// Player 1 wins
Console.Write( "Player 1" );
}
else
{
// Player 2 wins
Console.Write( "Player 2" );
}
}
}
// Driver code
public static void Main(String[] args)
{
int []arr = { 2, 4, 8 };
int N = arr.Length;
findWinnerGameRemoveGCD(arr, N);
}
} // This code is contributed by 29AjayKumar |
<script> // JavaScript program to implement // the above approach // Function to find the winner of the game by // removing array elements whose GCD is 1 function findWinnerGameRemoveGCD(arr, n)
{ // mp[i]: Stores count of array
// elements whose prime factor is i
let mp = new Map();
// Traverse the array
for (let i = 0; i < n; i++) {
// Calculate the prime factors
// of arr[i]
for (let j = 2; j * j <= arr[i];j++) {
// If arr[i] is divisible by j
if (arr[i] % j == 0) {
// Update mp[j]
if (mp.has(j)){
mp.set(j,mp.get(j)+1);
}
else mp.set(j,1);
while (arr[i] % j == 0) {
// Update arr[i]
arr[i] = Math.floor(arr[i] / j);
}
}
}
// If arr[i] exceeds 1
if (arr[i] > 1) {
if (mp.has(arr[i])){
mp.set(arr[i],mp.get(arr[i])+1);
}
else mp.set(arr[i],1);
}
}
// Stores maximum value
// present in the Map
let maxCnt = 0;
// Traverse the map
for (let [i,j] of mp) {
// Update maxCnt
maxCnt = Math.max(maxCnt,j);
}
// If n is an even number
if (n % 2 == 0) {
// If maxCnt is greater
// than or equal to n-1
if (maxCnt >= n - 1) {
// Player 1 wins
document.write( "Player 1" );
}
else {
// Player 2 wins
document.write( "Player 2" );
}
}
else {
// If maxCnt equal to n
if (maxCnt == n) {
// Player 1 wins
document.write( "Player 1" );
}
else {
// Player 2 wins
document.write( "Player 2" );
}
}
} // Driver Code let arr = [ 2, 4, 8 ]; let N = arr.length; findWinnerGameRemoveGCD(arr, N); // This code is contributed by shinjanpatra </script> |
Player 1
Time Complexity: (N * sqrt(X)), where X is the largest element of the array
Auxiliary Space: O(N)