Good Bye 2022: 2023 is NEAR C
Good Bye 2022: 2023 is NEAR C
第一道题真是没理解,wa了好多次
还好后来知道了题意就好做了,我现在在这里就补一下c,之前想了一会,还是不明白,后来想到了一些,容我讲一讲
这道题是给你n个数,问我们可以找到一个x,让每一个a[i]+x,然后让这些数两两gcd=1
而这里最关键的消息就是我不明白的那个点
这里用到一个知识点就是如果存在一个x ,每一个数对x取余,众所周知,对x取余一定有0到x-1这些数,只要每余数出现的次数都大于2,那么就一定不存在一个数可以让两两gcd=1
我理解的就是,假如这一个x是5,那么余数为0,1,2,3,4,的数量都大于等于2,不管加哪一个数,都可以让任意两个数gcd不等于1
如加4,那么余数为1的这些数的gcd是5,如果是2,那么余数为3的这些数gcd是5,如果是10,(10%5=0),那么那些余数是0的那些数gcd是5,任意数%5一定是0到4(设为t),那么对于那n个数对5取余的余数加上t为5(凑满5)的数量一定会大于等于2,那么一定会存在一对数gcd不为1,故此时一定是不存在一个数满足题目要求的
刚好这道题最大的数量是100(n<=100),那么我们只需要例举2到50的情况,大于50一定不存在让0到x-1的余数的数量大于2
详细的做法见代码
#include <iostream>
#include <vector>
#include <map>
using namespace std;
const int maxn=110;
#define int long long
int a[maxn];
int n;
void solve()
{
cin>>n;
map<int,int>vis;
bool yes=true;
for (int i=1;i<=n;i++)
{
cin>>a[i];
if (vis[a[i]]) yes=false;
vis[a[i]]++;
}
if (!yes)
{
cout<<"NO\n";
return ;
}
for (int i=2;i<=50;i++)
{
vis.clear();
bool ans=false;
for (int j=1;j<=n;j++)
{
vis[a[j]%i]++;
}
for (int j=0;j<i;j++)
{
if (vis[j]<2)
{
ans=true;
break;
}
}
if (!ans)
{
cout<<"NO\n";
return ;
}
}
cout<<"YES\n";
return ;
}
signed main ()
{
int t;
cin>>t;
while (t--)
{
solve();
}
system ("pause");
return 0;
}

浙公网安备 33010602011771号