我需要一些问题的帮助。我最近在一次采访中得到了这个,我试图解决它,但是没有运气。这是问题:
编写一个由两个玩家组成的游戏的算法。输入是一个正整数x。每一轮,玩家从数字中扣除一个完美的平方。玩家可以选择任何理想的正方形,只要该正方形小于或等于当前数字且大于0。如果扣除后数字变为0,则当前玩家获胜。
我认为这应该使用动态编程/贪婪方法来完成,我不太熟悉。否则我们可能需要得出一系列获胜/失败数字,如果玩家最终以获胜序列结束,无论如何他都会获胜。但是我们如何提出这样的顺序?
有人可以用Java解决这个问题吗?
更新:
DAle建议的解决方案1:
public int subtractPerfectSquares(int n)
{
if (n <= 0)
return 1;
boolean[] isWinningCase = new boolean[n + 1];
for (int i = 1; i <= n; i++)
{
for (int num = 1; num * num <= i; num++)
{
if (!isWinningCase[i - (num * num)])
{
isWinningCase[i] = true;
break;
}
}
}
return isWinningCase[n] ? 1 : 2;
}
对Solution2进行了修改以便更好地理解:
public int subtractPerfectSquares2(int n)
{
if (n <= 0)
return 1;
boolean[] isWinningCase = new boolean[n + 1];
// if we reach 0, we win
isWinningCase[0] = true;
// 1 is a win
isWinningCase[1] = true;
// 2 is a losing condition. We must define this as this state dictates losing scenarios for further states
isWinningCase[2] = false;
// we start from 3
for (int i = 3; i <= n; i++)
{
for (int num = 1; num * num <= i; num++)
{
int prefectSquare = num * num;
// if we get to 0 from current number or if we get to a losing scenario (to be faced by next player) from current number, then the current state is a winning position
if (i - prefectSquare == 0 || !isWinningCase[i - prefectSquare])
{
isWinningCase[i] = true;
break;
}
}
}
// return player 1 if given number is a winning state else player 2 wins
return isWinningCase[n] ? 1 : 2;
}
答案 0 :(得分:1)
此游戏中玩家之间的唯一区别是玩家1排名第一。这类游戏称为impartial game,两个玩家的完美策略都相同。此外,我们可以使用以下规则将游戏的所有状态(整数x
)分为两种类型:获胜位置或失落位置:
x=0
是亏损职位x
是获胜位置。x
是亏损位置。然后,我们需要确定从1
到x
的所有职位的类型。可能的实现:
boolean[] isWinning = new boolean[x+1];
for (int state = 0; state <= x; ++state) {
isWinning[state] = false;
for (int i = 1; i*i <= state; ++i) {
int perfectSquare = i*i;
if (!isWinning[state - perfectSquare]) {
isWinning[state] = true;
break;
}
}
}
如果当前玩家处于获胜位置(isWinning[x] == true
),则应该选择isWinning[x - perfectSquare] == false
这样的完美正方形。这将使游戏(和另一个玩家)处于失败位置。如果玩家处于失败位置,那么什么也救不了他,每个可能的完美平方都同样糟糕。
答案 1 :(得分:1)
下面的程序将帮助您实现逻辑。我已尝试根据您的要求实施代码。请确保在需要改进时发表评论,或者澄清对逻辑的误解。
public class Game {
public static void main(String[] args) {
int number = 0;
int count = 1;
int player = 1;
System.out.println("Please Enter a positive integer");
try (Scanner sc = new Scanner(System.in);) {
number = sc.nextInt();
while (number > 0) {
int numberArray[] = generatePerfectSquare(1, number);
System.out.println("===================");
System.out.println("perfect square numbers");
for (int i : numberArray) {
System.out.print(i);
System.out.print(" ");
}
System.out.println("");
System.out.println("===================");
player = ((count % 2 == 0) ? 2 : 1);
System.out.println("Round : " + count + " Player : " + player);
System.out.println("Please Enter your prefered perfect square number");
number = number - sc.nextInt();
if (number <= 0) {
System.out.println("****************");
System.out.println("You won the game");
System.out.println("===================");
} else {
System.out.println("===================");
System.out.println("You should try more");
System.out.println("===================");
}
count++;
}
} catch (Exception e) {
System.out.println(e);
}
}
private static int[] generatePerfectSquare(int start, int end) {
if (start > end || start < 0) {
throw new IllegalArgumentException();
}
int[] perfectSquares = new int[end - start];
int n = 0;
int candidate = (int) Math.ceil(Math.sqrt(start));
int square;
while ((square = candidate * candidate) < end) {
perfectSquares[n++] = square;
candidate++;
}
return Arrays.copyOf(perfectSquares, n);
}
测试结果