好久没写过题解了....得找回一下原来写题解总结的习惯
题目大意:
就是现在Ivica和Marica两个人在玩一个游戏
初始的时候,有一个数m = 1,现在连个人轮流对m进行改变,每次可以选择将m变为原来的2倍,或者将m加上1,并且不能使改变后的值比n大,谁将m变为n谁就输了
给定n,Ivica先手,假定两个人都足够聪明,问谁一定会获胜
其中n <= 1e15, 每次 test case 的n的个数数小于等于5, 时间限制500ms
大致思路:
首先,谁走到n处谁就输,所以n是N点(必败点), 对于N - 1,一定是P点(必胜点)。
首先有一个明显的结论是如果n是偶数,那么先手一定败,也就是说,1是N点,这个很容易解释,就是1是一个奇数,先手无论采取怎样的操作都将使得齐变成偶数,这样,后手只需要每次都将n变成奇数( + 1)即可,最终先手都会使得m变成n,先手必败。
这个也可以从下面这个方法中分析出来:
首先若n是偶数,那么不难发现[ n / 2, n]之间的数中,奇数都是P点,偶数都是N点,当n / 2是奇数时, [(n / 2 - 1) / 2, (n / 2 - 1)]之间的所有奇数数乘上2一定是[ n / 2, n]中的N点,而加上1一定是N点(偶数)所以 [(n / 2 - 1) / 2, (n / 2 - 1)]之间所有奇数数是P点,所有偶数是N点,(n / 2)是偶数时同理, 依次递推下去,当n是偶数时, 所有偶数是N点,所有奇数是P点,那么1是P点,所以n是偶数时Marica获胜。
当n是奇数时,如果(n + 1) / 2是奇数,(n - 1) / 2是偶数,则由[(n + 1) / 2, n]中所有奇数是N点,所有偶数是P点,那么(n - 1)/2乘上2到达偶数点P点,(n - 1) / 2也是N点, 同样的可以知道[(n - 1)/4 + 1, (n - 1) / 2]中的所有数都是N点,因为他们乘上二一定到达偶数点且属于[ (n + 1) / 2, n],那么[ (n - 1) /. 4 + 1, (n - 1) / 2]中的所有点是N点,而对于(n - 1) / 4, 无论加上1(变成(n - 1)/ 4 + 1)还是乘上2(变成(n - 1) / 2)都是到达N点, 那么(n - 1) / 4是P点, 这样我们可以发现一个问题:
我们可以讲所有大于n的点看成是N点, 这样对于(n + 1) / 2是奇数时可以发现, n的位置和(n - 1) / 4 + 1的位置具有一样的性质,也就是说n和(n - 1) / 4 + 1具有一样的结果。
同样的当(n + 1) / 2是偶数时,(n + 1) / 4和n有一样的性质。
这样每次向下找与n同样的性质的数(变成(n + 1) /4或是变成(n + 3) / 4)如果还是奇数就继续,如果变成了1,说明此时的n对应1是N点,Ivica获胜,如果n变成了偶数,说明1是P点,Marica获胜
代码如下:
Result : Accepted Time : 10 ms Memory : 2662 KB
/*
* Author: Gatevin
* Created Time: 2014/11/7 12:30:54
* File Name: hehe.cpp
*/
#include<iostream>
#include<sstream>
#include<fstream>
#include<vector>
#include<list>
#include<deque>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cmath>
#include<ctime>
#include<iomanip>
using namespace std;
const double eps(1e-8);
typedef long long lint;
lint n;
int t;
int main()
{
scanf("%d", &t);
while(t--)
{
//cin>>n;
scanf("%lld", &n);
if(n & 1)
{
while(n > 2 && (n & 1))
{
if(((n + 1)/2) & 1)
n = (n + 3) / 4;
else
n = (n + 1) / 4;
}
if(n == 1)
{
printf("Ivica\n");
continue;
}
printf("Marica\n");
}
else
{
printf("Marica\n");
continue;
}
}
return 0;
}