Gym - 102302G ( SG博弈 )

Gym - 102302G ( SG博弈 )

Tomaz and Danftito are playing a game with 3 stacks of rocks, each with ab and crocks respectively. Each turn, a player must take from 1 to m rocks from a stack, but they can't empty a stack if there are rocks in any stack to the left. The player that removes the last rock wins. If Tomaz goes first and they take turns playing, determine who will win the game if both players play optimally.

Input

The input contains one line with four integers: m (1 ≤ m ≤ 1018) representing the maximum amount of rocks to be removed in a single turn, ab and c (1 ≤ a, b, c ≤ 1018) each representing how many rocks there are initially in the first, second and third stacks respectively.

Output

Print "Tomaz" if Tomaz will win the game, and "Danftito" otherwise.

Example

Input

3 1 1 1

Output

Tomaz

题意:现在有三堆石子,两个人轮流拿1~k个石子,谁先拿完谁就赢了。附加了一个条件是如果这一堆石子左边堆里还有石子,那么你不能清空这个堆。

思路:假设从左到右三堆石头标号1,2,3;含有石子n,m,k个。往sg的方向想,如果没有那个限制条件的话很明显答案应该是sg(1)^sg(2)^sg(3) 三个堆的异或值。现在加上这个条件了,容易想到最左边的是不受影响的,中间的和右边的会受左边影响可能不能清空,那我们就假设2堆只有m-1个石子,3堆只有k-1个石子,那么这时候所有堆都是能清空的,也就没有了附加条件。这样sg完了以后,2,3堆分别还剩了一个石子,因为是偶数操作,所以不影响我们的sg结果,该先手赢的还是先手赢。

注:在if里面直接 ans1^ans2^ans3==0 直接wa4了。 结果加了个括号就A了。(==的优先级是7,^的优先级是9; 所以应该加括号)

还有,刚开始直接把sg都优化成0和1了。其实sg的值不一定就非得是0或1, 结合sg的定义,就是在所有子情况的sg中找一个没出现过的最小的值,就很好理解了。

代码:

#include 

using namespace std;

typedef long long ll;
ll a,b,c,n;
ll ans1,ans2,ans3;

int main()
{
    cin >> n >> a >> b >> c;
    ans1 = a%(n+1);
    ans2 = (b-1)%(n+1);
    ans3 = (c-1)%(n+1);

    if ( (ans1^ans2^ans3)==0 ) {
        cout << "Danftito" << endl;
    }
    else {
        cout << "Tomaz" << endl;
    }

    return 0;
}

 

你可能感兴趣的:(SG博弈)