1. 程式人生 > 實用技巧 >CF449C Jzzhu and Apples 思維題

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;
}