📌  相关文章
📜  最大的奇数除数游戏,检查哪个玩家获胜

📅  最后修改于: 2021-04-27 17:17:46             🧑  作者: Mango

两个玩家正在玩一个以n开头的游戏。在每一回合中,玩家可以进行以下任一动作:

  • 用n除以大于1的任何奇数除数。数字的除数包括数字本身。
  • 如果n> k,则从n中减去1,其中k

玩家1进行主要动作,如果玩家1获胜,则打印“是”,否则,如果两者均发挥最佳效果,则打印“否”。无法采取行动的玩家将输掉比赛。
例子:

方法:想法是分析以下三种情况的问题:

  • 当整数n为奇数时,玩家1可以自己除以n,因为它是奇数,因此n / n = 1,玩家2输了。注意,这里n = 1是一个例外。
  • 当整数n为偶数且奇数除数不大于1时, n的形式为2 x 。玩家1必然将其减去1,从而使n变为奇数。因此,如果x> 1,则玩家2获胜。请注意,对于x = 1,n – 1等于1,因此玩家1获胜。
  • 整数n为偶数且具有奇数除数时,任务仍然是检查n是否可被4整除,然后玩家1可以将n除以其最大的奇数因子,之后n的形式为2 x ,其中x> 1,因此玩家1再次获胜。
  • 否则,n必须为2 * p形式,其中p为奇数。如果p是质数,则玩家1输了,因为他可以将n减1或除以p,这两种情况都会对他造成损失。如果p不是素数,则p的形式必须为p1 * p2,其中p1是素数,p2是任何大于1的奇数,玩家1可以通过将n除以p2获胜。

下面是上述方法的实现:

C++
// C++ implementation to find the
// Largest Odd Divisor Game to
// check which player wins
#include 
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 tha 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 Divisior Game to
// check which player wins
import java.util.*;
  
class GFG{
      
// Function to find the
// Largest Odd Divisior 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 tha 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 tha 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 Divisior Game to
// check which player wins
using System;
   
class GFG{
       
// Function to find the
// Largest Odd Divisior 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 tha 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


输出:
No

时间复杂度: O(sqrt(n))
辅助空间: O(1)