每一年都奔走在自己热爱里

没有人是一座孤岛,总有谁爱着你

Good Bye 2022: 2023 is NEAR C

Good Bye 2022: 2023 is NEAR C

第一道题真是没理解,wa了好多次

还好后来知道了题意就好做了,我现在在这里就补一下c,之前想了一会,还是不明白,后来想到了一些,容我讲一讲

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;

}
posted @   righting  阅读(53)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示