CF449C Jzzhu and Apples 思维题

题意:

戳这里

分析:

思维题,原谅我没有思维

我们从大到小枚举质因数,有相同质因数的数可以匹配

对于每一个质因数,若它的倍数中未匹配的个数为偶数,那么两两匹配就是全部消掉了,若个数为奇数,那么将这个质因数的二倍剩下来,其他数两两匹配,为什么这样更优呢?因为我们从小到大枚举质因数,最后剩下的数一定是 2 的倍数,那么最后每个质因数剩下来的数一定会在枚举 2 的时候被匹配到

代码:

#include<bits/stdc++.h>

using namespace std;

namespace zzc
{
	inline int read()
	{
		int x=0,f=1;char ch=getchar();
		while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
		while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
		return x*f;
	}
	
	const int maxn = 1e5+5;
	int n,cnt=0,len,num;
	int p[maxn],tmp[maxn],ans[maxn][2];
	bool vis[maxn];
	
	void init()
	{
		for(int i=2;i<=50000;i++)
		{
			if(!vis[i])
			{
				p[++cnt]=i;
			}
			for(int j=1;j<=cnt&&i*p[j]<=50000;j++)
			{
				vis[i*p[j]]=true;
				if(i%p[j]==0) break;
			}
		}
	}
	
	void work()
	{
		init();
		n=read();
		memset(vis,false,sizeof(vis));
		for(int i=cnt;i;i--)
		{
			len=0;
			for(int j=p[i];j<=n;j+=p[i]) if(!vis[j]) tmp[++len]=j;
			if(len&1)
			{
				swap(tmp[len],tmp[2]);
				len--;
			}
			for(int j=1;j<=len;j+=2)
			{
				vis[tmp[j]]=vis[tmp[j+1]]=true;
				ans[++num][0]=tmp[j];
				ans[num][1]=tmp[j+1];
			}
		}
		printf("%d\n",num);
		for(int i=1;i<=num;i++) printf("%d %d\n",ans[i][0],ans[i][1]);
	}

}

int main()
{
	zzc::work();
	return 0;
}

posted @ 2020-11-16 11:15  youth518  阅读(98)  评论(0编辑  收藏  举报