El juego del divisor impar más grande para comprobar qué jugador gana

Dos jugadores están jugando un juego que comienza con un número n . En cada turno, un jugador puede realizar cualquiera de los siguientes movimientos: 
 

  • Divide n por cualquiera de sus divisores impares mayores que 1. Los divisores de un número incluyen el número mismo.
  • Reste 1 de n si n > k donde k < n.

El jugador 1 hace el movimiento principal, imprime «sí» si el jugador 1 gana; de lo contrario, imprime «no» si ambos juegan de manera óptima. El jugador que no puede hacer un movimiento pierde el juego.
Ejemplos: 
 

Entrada: n = 12, k = 1 
Salida: Sí 
Explicación: 
Jugador 1 primer movimiento = 12 / 3 = 4 
Jugador 2 primer movimiento = 4 – 1 = 3 
Jugador 1 segundo movimiento = 3 / 3 = 1 
Jugador 2 segundo movimiento puede ser hecho y por lo tanto pierde. 
Entrada: n = 1, k = 1
Salida: No 
Explicación: 
El primer movimiento del jugador 1 no es posible porque n = k y, por lo tanto, el jugador 1 pierde.
 

Planteamiento: La idea es analizar el problema para los siguientes 3 casos:
 

  • Cuando el entero n es impar , el jugador 1 puede dividir n por sí mismo, ya que es impar y, por lo tanto, n/n = 1, y el jugador 2 pierde. Tenga en cuenta que aquí n = 1 es una excepción.
  • Cuando el entero n es par y no tiene divisores impares mayores que 1 , entonces n tiene la forma 2 x . El jugador 1 está obligado a restarlo por 1 haciendo n impar. Entonces, si x > 1, el jugador 2 gana. Tenga en cuenta que para x = 1, n – 1 es igual a 1, por lo que el jugador 1 gana.
  • Cuando el número entero n es par y tiene divisores impares , la tarea sigue siendo verificar si n es divisible por 4, entonces el jugador 1 puede dividir n por su factor impar más grande, después de lo cual n se vuelve de la forma 2 x donde x > 1, así que de nuevo el jugador 1 gana
  • De lo contrario, n debe ser de la forma 2 * p , donde p es impar. Si p es primo , el jugador 1 pierde, ya que puede reducir n por 1 o dividirlo por p, lo cual sería una pérdida para él. Si p no es primo entonces p debe ser de la forma p1 * p2 donde p1 es primo y p2 es cualquier número impar > 1, para el cual el jugador 1 puede ganar dividiendo n entre p2.

A continuación se muestra la implementación del enfoque anterior:
 

C++

// C++ implementation to find the
// Largest Odd Divisor Game to
// check which player wins
#include <bits/stdc++.h>
using namespace std;
 
// Function to find the
// Largest Odd Divisor Game to
// check which player wins
void findWinner(int n, int k)
{
    int cnt = 0;
 
    // Check if n == 1 then
    // player 2 will win
    if (n == 1)
        cout << "No" << endl;
 
    // Check if n == 2 or n is odd
    else if ((n & 1) or n == 2)
        cout << "Yes" << endl;
 
    else {
        int tmp = n;
        int val = 1;
 
        // While n is greater than k and
        // divisible by 2 keep
        // incrementing the val
        while (tmp > k and tmp % 2 == 0) {
            tmp /= 2;
            val *= 2;
        }
 
        // Loop to find greatest
        // odd divisor
        for (int i = 3; i <= sqrt(tmp); i++) {
            while (tmp % i == 0) {
                cnt++;
                tmp /= i;
            }
        }
        if (tmp > 1)
            cnt++;
 
        // Check if n is a power of 2
        if (val == n)
            cout << "No" << endl;
 
        else if (n / tmp == 2 and cnt == 1)
            cout << "No" << endl;
 
        // Check if cnt is not one
        // then player 1 wins
        else
            cout << "Yes" << endl;
    }
}
 
// Driver code
int main()
{
    long long n = 1, k = 1;
    findWinner(n, k);
    return 0;
}

Java

// Java implementation to find the
// Largest Odd Divisor Game to
// check which player wins
import java.util.*;
 
class GFG{
     
// Function to find the
// Largest Odd Divisor Game to
// check which player wins
public static void findWinner(int n, int k)
{
    int cnt = 0;
 
    // Check if n == 1 then
    // player 2 will win
    if (n == 1)
        System.out.println("No");
     
    // Check if n == 2 or n is odd
    else if ((n & 1) != 0 || n == 2)
        System.out.println("Yes");
 
    else
    {
        int tmp = n;
        int val = 1;
 
        // While n is greater than k and
        // divisible by 2 keep
        // incrementing the val
        while (tmp > k && tmp % 2 == 0)
        {
            tmp /= 2;
            val *= 2;
        }
 
        // Loop to find greatest
        // odd divisor
        for(int i = 3;
                i <= Math.sqrt(tmp); i++)
        {
           while (tmp % i == 0)
           {
               cnt++;
               tmp /= i;
           }
        }
        if (tmp > 1)
            cnt++;
 
        // Check if n is a power of 2
        if (val == n)
            System.out.println("No");
 
        else if (n / tmp == 2 && cnt == 1)
            System.out.println("No");
 
        // Check if cnt is not one
        // then player 1 wins
        else
            System.out.println("Yes");
    }
}
 
// Driver code
public static void main(String[] args)
{
    int n = 1, k = 1;
     
    findWinner(n, k);
}
}
 
// This code is contributed by jrishabh99

Python3

# Python3 implementation to find 
# the Largest Odd Divisor Game
# to check which player wins
import math 
 
# Function to find the Largest
# Odd Divisor Game to check
# which player wins
def findWinner(n, k):
     
    cnt = 0;
 
    # Check if n == 1 then
    # player 2 will win
    if (n == 1):
        print("No");
 
    # Check if n == 2 or n is odd
    elif ((n & 1) or n == 2):
        print("Yes");
 
    else:
        tmp = n;
        val = 1;
 
        # While n is greater than k and
        # divisible by 2 keep
        # incrementing the val
        while (tmp > k and tmp % 2 == 0):
            tmp //= 2;
            val *= 2;
             
        # Loop to find greatest
        # odd divisor
        for i in range(3, int(math.sqrt(tmp)) + 1):
            while (tmp % i == 0):
                cnt += 1;
                tmp //= i;
         
        if (tmp > 1):
            cnt += 1;
 
        # Check if n is a power of 2
        if (val == n):
            print("No");
 
        elif (n / tmp == 2 and cnt == 1):
            print("No");
 
        # Check if cnt is not one
        # then player 1 wins
        else:
            print("Yes");
             
# Driver code
if __name__ == "__main__":
 
    n = 1; k = 1;
     
    findWinner(n, k);
 
# This code is contributed by AnkitRai01

C#

// C# implementation to find the
// Largest Odd Divisor Game to
// check which player wins
using System;
  
class GFG{
      
// Function to find the
// Largest Odd Divisor Game to
// check which player wins
public static void findWinner(int n, int k)
{
    int cnt = 0;
  
    // Check if n == 1 then
    // player 2 will win
    if (n == 1)
        Console.Write("No");
      
    // Check if n == 2 or n is odd
    else if ((n & 1) != 0 || n == 2)
        Console.Write("Yes");
  
    else
    {
        int tmp = n;
        int val = 1;
  
        // While n is greater than k and
        // divisible by 2 keep
        // incrementing the val
        while (tmp > k && tmp % 2 == 0)
        {
            tmp /= 2;
            val *= 2;
        }
  
        // Loop to find greatest
        // odd divisor
        for(int i = 3;
                i <= Math.Sqrt(tmp); i++)
        {
           while (tmp % i == 0)
           {
               cnt++;
               tmp /= i;
           }
        }
        if (tmp > 1)
            cnt++;
  
        // Check if n is a power of 2
        if (val == n)
            Console.Write("No");
  
        else if (n / tmp == 2 && cnt == 1)
            Console.Write("No");
  
        // Check if cnt is not one
        // then player 1 wins
        else
            Console.Write("Yes");
    }
}
  
// Driver code
public static void Main(string[] args)
{
    int n = 1, k = 1;
      
    findWinner(n, k);
}
}
// This code is contributed by rutvik_56

Javascript

<script>
 
// Javascript implementation to find the
// Largest Odd Divisor Game to
// check which player wins
       
// Function to find the
// Largest Odd Divisor Game to
// check which player wins
function findWinner(n, k)
{
    let cnt = 0;
   
    // Check if n == 1 then
    // player 2 will win
    if (n == 1)
        document.write("No");
       
    // Check if n == 2 or n is odd
    else if ((n & 1) != 0 || n == 2)
        document.write("Yes");
   
    else
    {
        let tmp = n;
        let val = 1;
   
        // While n is greater than k and
        // divisible by 2 keep
        // incrementing the val
        while (tmp > k && tmp % 2 == 0)
        {
            tmp /= 2;
            val *= 2;
        }
   
        // Loop to find greatest
        // odd divisor
        for(let i = 3;
                i <= Math.sqrt(tmp); i++)
        {
           while (tmp % i == 0)
           {
               cnt++;
               tmp /= i;
           }
        }
        if (tmp > 1)
            cnt++;
   
        // Check if n is a power of 2
        if (val == n)
            document.write("No");
   
        else if (n / tmp == 2 && cnt == 1)
            document.write("No");
   
        // Check if cnt is not one
        // then player 1 wins
        else
            document.write("Yes");
    }
}
 
// Driver Code
     
    let n = 1, k = 1;
       
    findWinner(n, k);
    
   // This code is contributed by splevel62.
</script>
Producción: 

No

 

Complejidad de tiempo: O(sqrt(n)) 
Espacio auxiliar: O(1)
 

Publicación traducida automáticamente

Artículo escrito por rishabhtyagi2306 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *