標籤:style color os width io art
E. Jzzhu and Applestime limit per test1 secondmemory limit per test256 megabytesinputstandard inputoutputstandard output
Jzzhu has picked n apples from his big apple tree. All the apples are numbered from 1 to n. Now he wants to sell them to an apple store.
Jzzhu will pack his apples into groups and then sell them. Each group must contain two apples, and the greatest common divisor of numbers of the apples in each group must be greater than 1. Of course, each apple can be part of at most one group.
Jzzhu wonders how to get the maximum possible number of groups. Can you help him?
Input
A single integer n (1?≤?n?≤?105), the number of the apples.
Output
The first line must contain a single integer m, representing the maximum number of groups he can get. Each of the next m lines must contain two integers — the numbers of apples in the current group.
If there are several optimal answers you can print any of them.
Sample test(s)input
6
output
26 32 4
input
9
output
39 32 46 8
input
2
output
0
思路:這題剛開始確實想不到的。看了別人的解題報告才知道怎麼搞。
因為只要最大公約數>1,所以偶數的組合肯定可以。但是奇數的就有點難搞了。如果用加倍的方法來組成一對的話那不是最多的情況。但是多加兩位就是最多的情況了,這是前20名的代碼中的做法。我沒想明白。後面才感覺這得想到才行。因為奇數加兩位之後為偶數的機率比較小,就不和偶數的組合情況重複了,然後又可以把奇數組合成一對。這太機智了。比賽的時候確實很難想出來。
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<map>#include<queue>#include<set>#include<bitset>#define mem(a,b) memset(a,b,sizeof(a))#define INF 1000000070000using namespace std;typedef long long ll;typedef unsigned long long ull;int vis[100005],is[100005];vector<pair<int,int> >v;int main(){ int n,i,j; cin>>n; for(i=4;i<=n;i+=2) vis[i]=1; for(i=3;i<=n;i+=2) { if(!vis[i]) { if(i*2>n) break; vector<int>a; for(j=i;j<=n;j+=2*i) { vis[j]=1; if(!is[j]) a.push_back(j),is[j]=1; } for(j=a.size()-1;j>0;j-=2) { v.push_back(make_pair(a[j],a[j-1])); is[a[j]]=is[a[j-1]]=1; } if(a.size()&1) { v.push_back(make_pair(a[0],a[0]*2)); is[a[0]]=is[a[0]*2]=1; } } } if(n&1) n--; int x=0,y; for(i=n;i>0;i-=2) { if(is[i]) continue; if(!x) y=i,x=1; else x=0,v.push_back(make_pair(i,y)); } printf("%d\n",v.size()); for(i=0;i<v.size();i++) printf("%d %d\n",v[i].first,v[i].second); return 0;}