以下问题来自最近的编程竞赛。
GCD游戏
生与死,无论输赢,都有两面性。这就是Arjit和Chandu Don所争论的。他们厌倦了彼此之间的团结战争,因此决定像数学领域的男人一样定居 但即使在玩数学游戏时,他们还没有放弃相互伤害的策略。所以,Arjit带着一些自己的橡皮子弹,而Chandu Don带着b个橡皮子弹。因为,Little Chandu是两个中更危险的黑帮,他决定给Arjit第一次机会。1. If GCD (a, b) is greater than 1, then, the player can:
a.) Subtract 1 from opposite player’s bullets. **OR**
b.) Divide the number of bullets of opposite player by GCD (a, b).
2. If GCD (a, b) is equal to 1, then, the player can:
a.) Subtract 1 from the opposite player’s bullets.
Note : Player can choose only one move out of two if GCD(A,B) > 1 .
The one who ends up with only one bullet loses the battle,
and his life, and the land of HEpur.
一劳永逸地确定谁将统治!
输入:
第一行包含测试用例T的数量,接下来的T行包含分别由Arjit和Chandu Don拍摄的两个数字A和B.
输出:
在平局打印Draw的情况下打印游戏的赢家名称。
约束
1 <= T <= 1000
1 <= A <= 1000
1 <= B <= 1000
问题陈述信用:Arjit Srivastava。
Sample Input
4
2 1
3 4
5 5
1 1
Sample Output
Arjit
Chandu Don
Arjit
Draw
我在这里添加我的解决方案:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class TestClass
{
public static void main(String args[] ) throws Exception
{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int noOfTestCases = Integer.parseInt( br.readLine() );
for( int inx = 0; inx < noOfTestCases; ++inx )
{
StringTokenizer st = new StringTokenizer( br.readLine() );
int a = 0;
int b = 0;
while( st.hasMoreTokens())
{
a = Integer.parseInt( st.nextToken() );
b = Integer.parseInt( st.nextToken() );
}
doStuff( a, b, true);
}
}
private static boolean doStuff(int a, int b, boolean arjitInPlay )
{
if( a == 1 && b == 1 )
{
System.out.println( "Draw" );
return true;
}
if( a == 1 )
{
System.out.println( "Chandu Don" );
return true;
}
if( b == 1 )
{
System.out.println( "Arjit" );
return true;
}
int result = getGCD( a, b );
if( arjitInPlay )
{
if( result > 1 )
{
return doStuff( a, b - 1, !arjitInPlay ) || doStuff( a, b / result, !arjitInPlay );
}
else if ( result == 1 )
{
return doStuff( a, b - 1, !arjitInPlay );
}
}
else
{
if( result > 1 )
{
return doStuff( a - 1, b, !arjitInPlay ) || doStuff( a / result, b, !arjitInPlay );
}
else if ( result == 1 )
{
return doStuff( a - 1, b, !arjitInPlay );
}
}
return false;
}
private static int getGCD(int a, int b)
{
if (b == 0)
{
return a;
}
return getGCD(b, a % b);
}
}
我在这里有两个问题:
感谢, 帕。
答案 0 :(得分:0)
我还没有尝试在任何自动判断系统上解决问题,但我有以下建议:
假设他们发挥得最好。
根据约束,使用递归是完全正确的,但是你的实现有一个bug。你的代码所做的只是每个回合,每个用户从相反的中移除1个子弹,我认为你的短路中的第二个函数调用没有被执行。换句话说,您的代码将声明拥有更多项目符号的人作为获胜者。您可以尝试8 5
作为输入。你的代码输出'Arjit',但实际上它应该是'Chandu Don'。
恕我直言,解决问题的最佳方法是使用3D数组win[i][j][k]
,而不是像DFS一样完成计算方法,而不是像DFS那样,表示玩家{{1}当玩家0拥有k
个子弹而玩家1拥有i
个子弹时,他将会获胜。请注意,绘制游戏只能在输入为j
时发生。
以玩家0为例,1 1
为win[i][j][0]
当且仅当True
为win[i][j - 1][1]
或False
时(如果win[i][j / gcd(i, j)][1]
)是gcd(i, j) > 1
。玩家1的计算方法类似。
我知道这与您的想法基本相同,但通过这样做,可以为所有False
缓存计算结果,因此将来的查询/访问将非常快。