2020牛客暑期多校训练营(第四场)H题Harder Gcd Problem(贪心)

2020牛客暑期多校训练营(第四场)H题Harder Gcd Problem(贪心)

Harder Gcd Problem

题意:从n中取m对数,使每对数的gcd不为1,输出最大的m与方案;

题解:从最大的质因数往下枚举,如果为其倍数并且没用过的个数为偶数,则互相连接,如果为奇数个且大于1,将任意一个质因数的偶数倍的一个数的改为没用过(这里留一个偶数是留个最小的质因数2用),将其他数相互连接。

#include<iostream>
#include<vector>
using namespace std;
const int N=2e5+7;
int t,n,vis[N];
vector<int>G[N],ho,sa;
vector<pair<int,int > >ans;
bool isnot[N];
void getys(){
    for(int i=2;i<N;i++){
        if(!isnot[i]) {
            for (int j = i; j < N; j += i) {
                isnot[j] = true;
                G[i].push_back(j);
            }
        }
    }
}
int main(){
	getys();
	scanf("%d",&t);
	while(t--){
		ans.clear();
		scanf("%d",&n);
		for(int i=1;i<=n;i++)vis[i]=0;
		for(int i=n/2;i>=2;i--){
			ho.clear();
			if(G[i].size()==0)continue;
			for(int j=0;j<G[i].size();j++){
				if(G[i][j]>n)continue;
				if(!vis[G[i][j]]){
					vis[G[i][j]]=1;
					ho.push_back(G[i][j]);
				}
			}
			if(ho.size()%2==0){
				for(int j=0;j<ho.size();j+=2){
					ans.push_back({ho[j],ho[j+1]});
				}
			}
			else{
				int ok=0;
				sa.clear();
				for(int j=0;j<ho.size();j++){
					if(ho[j]%2==0&&!ok){
						vis[ho[j]]=0;
						ok=1;
					}
					else{
						sa.push_back(ho[j]);
					}
				}
				for(int j=0;j<sa.size();j+=2){
					ans.push_back({sa[j],sa[j+1]});
				}
			}
		}
		printf("%d\n",ans.size());
		for(int i=0;i<ans.size();i++){
			printf("%d %d\n",ans[i].first,ans[i].second);
		}
	}
}

posted @ 2020-07-22 13:43  ccsu_madoka  阅读(152)  评论(0编辑  收藏  举报