牛客多校 A 题题解
牛客多校 8 - A
Haitang and Game
Given a set
-
Find a pair
such that and . -
Insert
into .
The player who cannot make a move loses the game. You need to output the winner when both players play optimally.
Each test contains multiple test cases. The first line contains an integer
( ) — the number of test cases. The description of the test cases follows.
The first line of each test case contains a single integer
( ) — the size of set .
The second line contains
integers ( ) — the elements of set .
解题思路:
考场上这题没优化好导致
- 简单分析之后可以发现,无论两边最后怎么选,最后的形成的数列的个数是固定的,如果最后形成的数列的个数比原本的数列的个数增加奇数个,那么
胜利, 否则 胜利. - 而要怎么找出所有的可能插入的
呢? 首先,观察到数据范围在 的范围,我们可以开一个 类型的哈希表来记录在初始的集合中出现过的元素,然后我们枚举可能还可以在插入的数据 ( ) ,在枚举过程中,如果已经在集合中就直接跳过,如果不在集合中,就需要开始判断,判断的过程中,遍历 在 中 的倍数,这里注意,我考场上把每两个 的倍数都进行了 运算, 这样直接导致我考场上这一题 了几十发...... 实际上,只需要把所有的 的倍数的数一起求最大公因数,如果最大公倍数为 那么说明 最后需要被插入到集合 中.这里开始证明: 如果存在 与 的最大公因数为 ,就可以得出 , 和 互质, ,那么 . 下证必要性, 若存在 ,即 ,我们如何证明存在 呢? 该出采用反证法,如果 任意 与 都两两不互质,则 存在 公因数 ( )可以被提出来最后必然存在 ,与结论相悖 ,故可以得出, 若所有的 的倍数的元素的公因数是 ,那么必然存在最少一对 的倍数的元素的公因数是 ,若在 的倍数的元素中存在两个数的公因数是 ,那么必然存在所有的 的倍数的元素的公因数 ,也就是为 ,所以综上只需要求一下所有的 的倍数的元素的最大公因数并判断是否为 即可得出是否存在两个元素的 是否为 . - 总结: 对基本的数论知识不熟。
AC code:
#include <bits/stdc++.h>
#define print(x) cout<<#x<<'='<<x<<'\n'
using namespace std;
const int maxn = 1e5 + 9;
int a[maxn];
int read()
{
int x = 0, f = 1;
char c = getchar();
while (!isdigit(c))
{
if (c == '-')
f = -1;
c = getchar();
}
while (isdigit(c))
{
x = x * 10 + c - '0';
c = getchar();
}
return x * f;
}
int n;
int gcd(int x, int y)
{
return y == 0 ? x : gcd(y, x % y);
}
int ct=0;
void solve()
{
auto Y = [&]()
{
cout << "dXqwq" << "\n";
};
auto N = [&]()
{
cout << "Haitang" << '\n';
};
cin >> n;
vector<bool> mm(1e5 + 9, 0);
for (int i = 1; i <= n; i++)
{
cin >> a[i];
mm[a[i]] = 1;
}
int count = 0;
for (int _ = 50000; _ >= 1; _--)
{
// print(_);
if (!mm[_])
{
int t=0;
for (int i = 2*_; i <= 100000; i+=_)
{
if (mm[i])
{
t=__gcd(t,i);
}
}
if(t==_)
{
mm[_]=1;
count++;
}
}
}
if(count&1)
{
Y();
}
else N();
// print(++ct);
}
int main()
{
std::ios::sync_with_stdio(0);
std::cin.tie(0),cout.tie(0);
// freopen("1data.in","r",stdin);
int t;
// int st = clock();
cin >> t;
while (t--)
solve();
// int ed = clock();
// cerr << ed - st;
return 0;
}
任何时候都有比放弃更好的选择。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)