Description

\(1..n\) 中找两个不交的,大小分别为 \(m\) 的集合,它们存在一种配对方式,使得每对的最大公约数大于 \(1\)。求最大的 \(m\)

Solution

降序枚举所有质数,找到所有未被使用的它的倍数

若有偶数个则两两配对,若有奇数个则将 \(2p\) 留下来


所有大于 \(n/2\) 的质数和 \(1\) 都无法被配对

若其余的数有偶数个,则算法执行后没有剩余

若其余的数有奇数个,则算法执行后剩余 \(1\) 个数

故为一种最优解

#include <bits/stdc++.h>
using namespace std;

#define int long long
const int N = 200005;

int isp[N],a[N],n,t;

signed main()
{
    ios::sync_with_stdio(false);

    for(int i=2;i<N;i++)
    {
        isp[i]=1;
        for(int j=2;j*j<=i;j++)
        {
            if(i%j==0)
            {
                isp[i]=0;
                break;
            }
        }
    }

    cin>>t;
    while(t--)
    {
        cin>>n;
        for(int i=1;i<=n;i++) a[i]=1;
        vector <pair<int,int>> ans;
        for(int i=n/2;i>=2;--i)
        {
            if(isp[i])
            {
                vector<int> vec;
                for(int j=i;j<=n;j+=i)
                {
                    if(a[j])
                    {
                        vec.push_back(j);
                    }
                }
                if(vec.size()&1)
                {
                    for(int j=0;j<vec.size();j++)
                    {
                        if(vec[j]==i*2) vec.erase(vec.begin()+j);
                    }
                }
                for(int j=1;j<vec.size();j+=2)
                {
                    ans.push_back({vec[j],vec[j-1]});
                    a[vec[j]]=0;
                    a[vec[j-1]]=0;
                }
            }
        }
        cout<<ans.size()<<endl;
        for(int i=0;i<ans.size();i++) cout<<ans[i].first<<" "<<ans[i].second<<endl;
    }
}

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-02-09
猜你喜欢
  • 2022-12-23
  • 2021-07-25
  • 2021-08-28
  • 2021-11-09
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案