中石油第八次 取石子

typeryougishiki

2019-06-10 20:27:56

Personal

## 题面 题目描述 一天早上,机房里出现了n堆石子(雾),Tweetuzki和Miffoury开始把石子运到机房外面(Tweetuzki先开始)。不过他们觉得这样太无聊了,于是决定:每个人每次只搬运某堆中的石子,且搬运的数量必须是1或者是一个质数,如果谁没有办法继续搬运(也就是没有石子了),那么ta将会在明天开篇的《***-YC列传》中饰演公主的角色(大雾。 当然,在ta们的得到石子的来源之前,有连续的T个早上,ta们都会遇上类似的情况,即本题有多组数据。 输入 第一行一个数T,表示数据组数。 对于每组数据,输入会先给出一个数n,表示石子的堆数,加下来会给出n个数,表示每堆石子个数。 输出 T行,每行一个数表示答案,表示下周开篇的《***-YC列传》中的公主(即Tweetuzki或Miffoury)。 ## 思路 很明显这是个nim博弈,但是10的6次方的数据范围如果直接预处理SG值的话大概会超时,一眼也看不出来有啥规律。 于是在打了个0-1000的SG值的表,然后发现规律: |n | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |...| | -----------: | -----------: | -----------: | -----------: | -----------: | -----------: | -----------: | -----------: | -----------: | -----------:| -----------: | |sg(n)| 0 | 1 | 2 | 3 | 0 | 1 | 2 | 3 | 4 |...| 很明显,每个数的SG值是这个数对4求余,于是就可以直接nim和了。 注意这个题数据略大,直接cin会超时 代码 ```cpp #include<iostream> #include<algorithm> #include<queue> #include<cstring> #include<set> #include<cstdio> #pragma warning(disable: 4996) using namespace std; typedef int ll; int ans = 0; int main() { int t; cin >> t; while (t > 0) { t--; int n; cin >> n; for (int i = 1; i <= n; i++) { int num; scanf("%d",&num); num %= 4; ans ^= num; } if (ans == 0) { cout << "Tweetuzki\n"; } else cout << "Miffoury\n"; ans = 0; } return 0; } ```