两个玩家正在玩一个以n开头的游戏。在每一回合中,玩家可以进行以下任一动作:
- 用n除以大于1的任何奇数除数。数字的除数包括数字本身。
- 如果n> k,则从n中减去1,其中k
玩家1进行主要动作,如果玩家1获胜,则打印“是”,否则,如果两者均发挥最佳效果,则打印“否”。无法采取行动的玩家将输掉比赛。
例子:
Input: n = 12, k = 1
Output: Yes
Explanation:
Player 1 first move = 12 / 3 = 4
Player 2 first move = 4 – 1 = 3
Player 1 second move = 3 / 3 = 1
Player 2 second move can be done and hence he looses.
Input: n = 1, k = 1
Output: No
Explanation:
Player 1 first move is not possible because n = k and hence player 1 looses.
方法:想法是分析以下三种情况的问题:
- 当整数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)