CF449C Jzzhu and Apples (筛素数 数论?

Codeforces Round #257 (Div. 1) C

Codeforces Round #257 (Div. 1) E

CF450E

C. Jzzhu and Apples

time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard 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

题意:有N个苹果,编号为1~N。现要将苹果组成若干对,每对苹果最小公约数不为1。求最多能分成多少对,输出各对的组成。

题解:先筛素数,然后搞。

首先我们怕的是乱选了两个数组成了公约数不为1的一对,但是这导致了总对数减少(这两个数分别被别的数需要,它们组成一对了不是最优解)。为了防止这种情况,我们要想办法让总对数不会减少。

我们发现2的倍数们非常碉炸,任意2个就能组成1对,所以我们先弄其他的数,最后再搞2的倍数。

我们发现一个质数x的1倍、2倍、3倍、……?倍中未使用的数组成的集合,也可以任意两两组合,但是如果在1~n之间,这个集合的元素个数是奇数,就会多一个。为了不造成多余的影响,我们把2*x作为多出来的一个,扔到2的倍数中去。这样,各种集合的多出来的一个,肯定能找到配对。把我们使用的数标记一下,防止搞其他质数的时候重复用一个数。

先搞完3到小于等于(N/2)的质数(大于N/2,它的倍数的集合就只有它自己了,没法玩),然后搞2的倍数,把之前扔进来的2*x们和其他2*y(y是合数)组成一个大集合,两两配对,最后再多出来一个也没办法了,这已经是最多的配对了。

解不唯一,我们这样搞肯定能找到最多的对数,碉炸。

代码:

 1 //#pragma comment(linker, "/STACK:102400000,102400000")
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<iostream>
 5 #include<cstring>
 6 #include<algorithm>
 7 #include<cmath>
 8 #include<map>
 9 #include<set>
10 #include<stack>
11 #include<queue>
12 using namespace std;
13 #define ll long long
14 #define usll unsigned ll
15 #define mz(array) memset(array, 0, sizeof(array))
16 #define minf(array) memset(array, 0x3f, sizeof(array))
17 #define REP(i,n) for(i=0;i<(n);i++)
18 #define FOR(i,x,n) for(i=(x);i<=(n);i++)
19 #define RD(x) scanf("%d",&x)
20 #define RD2(x,y) scanf("%d%d",&x,&y)
21 #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
22 #define WN(x) prllf("%d\n",x);
23 #define RE  freopen("D.in","r",stdin)
24 #define WE  freopen("1biao.out","w",stdout)
25 #define mp make_pair
26 #define pb push_back
27
28 const long N = 100001;
29 int prime[N],pn = 0;
30 bool isnp[N];
31 void shai() {
32     int i,j;
33     memset(prime,0,sizeof(prime));
34     memset(isnp,0,sizeof(isnp));
35     isnp[0]=1,isnp[1]=1;
36     pn=0;
37     for(i = 2 ; i < N ; i ++) {
38         if(! isnp[i])
39             prime[pn ++]=i;
40         //关键处1
41         for(j = 0 ; j < pn && i * prime[j] <  N ; j ++) {
42             isnp[i * prime[j]] = 1;
43             if( !(i % prime[j] ) )  //关键处2
44                 break;
45         }
46     }
47 }
48
49 int n;
50 vector<int>a,a2;
51 vector<pair<int,int> >v;
52 bool used[N];
53 int main() {
54     int i,j,k;
55     int l,r,mid;
56     int pre;
57     int ans;
58     shai();
59     while(scanf("%d",&n)!=EOF) {
60         ans=0;
61         v.clear();
62         a2.clear();
63         memset(used,0,sizeof(used));
64
65         for(i=1; prime[i]<=n/2; i++) {
66             a.clear();
67             a.pb(prime[i]);
68             for(j=3*prime[i]; j<=n; j+=prime[i]) if(!used[j]) a.pb(j);
69             if(a.size()%2==0) a2.pb(2*prime[i]);
70             else a.pb(2*prime[i]);
71             int maxj=a.size();
72             for(j=0; j+1<maxj; j+=2) {
73                 v.pb(mp(a[j],a[j+1]));
74                 used[a[j]]=1;
75                 used[a[j+1]]=1;
76             }
77         }
78
79         if(n>=2)a2.pb(2);
80         if(n>=4)a2.pb(4);
81         for(i=4; i+i<=n; i++) {
82             if(!used[i+i] && isnp[i]) a2.pb(i+i);
83         }
84         int maxi=a2.size();
85         for(i=0; i+1<maxi; i+=2) v.pb(mp(a2[i],a2[i+1]));
86         printf("%d\n",v.size());
87         maxi=v.size();
88         REP(i,maxi) printf("%d %d\n",v[i].first,v[i].second);
89     }
90     return 0;
91 }

CF449C Jzzhu and Apples (筛素数 数论?

时间: 2024-10-04 20:46:47

CF449C Jzzhu and Apples (筛素数 数论?的相关文章

CodeForces 449C Jzzhu and Apples 数学+素数

这道题目晚上本来就花了很多把都××了,着实觉得自己思路没错啊,回顾一下思路,给你n个数,分成两两组合一对,分成最多组如何分,但是组合的两个数 不能互素,所以呢 偶数肯定是好的了,所以先放着,先把素数给搞定,10^5所以枚举所有包含该素数因子的数,如果刚好分组则最好,不然的话其中有偶数的踢掉一个给下面的偶数处理部分,最后再处理偶数的部分,这样肯定满足组数最多,完全没有问题,后来方法确实是没问题啊,只是代码有问题,我靠!真是脑残!,今天看到一位大牛的想法,我跟他是一样的,只是代码写搓了,后来改了又改

CF449C Jzzhu and Apples

传送门 这道题好像一开始想到了差不多的做法orz?后来都不大敢相信就是这么做的--有点瞎搞. 后来看了CF的官方题解,感觉还是挺有道理的.首先对于1和大于n/2的质数肯定是不行的,我们直接忽略.然后,对于每一个质数的倍数,我们肯定是把他们组合在一起更优.如果这些数有奇数个,那我们就把质数的2倍挑出来(因为2倍是最容易组合的!) 如果有偶数个就直接组合. 最后你肯定剩下的全都是偶数,那么随便组合就行啦! 直接用两个栈模拟即可. 看一下代码. #include<cstdio> #include&l

Codeforces 450E:Jzzhu and Apples(构造,数学)

E. Jzzhu and Apples time limit per test: 1 seconds memory limit per test: 256 megabytes input: standard input output: standard output Jzzhu has picked \(n\) apples from his big apple tree. All the apples are numbered from \(1\) to \(n\). Now he wants

Hrbust1328 相等的最小公倍数 (筛素数,素因子分解)

本文出自:http://blog.csdn.net/svitter/ 题意: 求解An 与 An-1是否相等. n分为两个情况-- 1.n为素数, 2.n为合数. =  =好像说了个废话..素数的时候,可以直接输出no,因为素数不可能和An-1相等.合数的时候,如果n是a^b次方,那么也是NO.原因很简单,之前数字的最小公倍数的n的因子次方数,不能超过n的次方数. //================================================================

Codeforces 449C Jzzhu and Apples(构造)

题目链接:Codeforces 449C Jzzhu and Apples 题目大意:Jzzhu从苹果树上获得n个苹果,标号从1~n,现在要将他们以两个为一组卖给商家,要求一组中的两个苹果的编号最大公约数大于1,分的组数尽量多. 解题思路:枚举公约数d,只枚举素数,因为合数的可以在更小的素数被枚举.将所有没用过并且编号为d的倍数的苹果拿出来,两两组队,如果个数为奇数,那么就将2d留出来.因为d>2,所以第2个肯定是2d.并且2d是2的倍数. #include <cstdio> #incl

Codeforces Round #257 (Div. 2) E题:Jzzhu and Apples 模拟

E. Jzzhu and Apples time limit per test 1 second memory limit per test 256 megabytes input standard input output standard 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

常见模板(欧拉筛素数,最小生成树,快排,并查集,单源最短路)

欧拉筛素数: #include<cstdio> #define maxn 10000000+10 using namespace std; int n,prime[5000001],num_prime=0,m; bool if_prime[maxn]; void euler(int limit) { for(int i=2;i<=limit;i++) { if(!if_prime[i]) prime[++num_prime]=i; for(int j=1;prime[j]*i<=l

洛谷 P3383 【模板】线性筛素数

P3383 [模板]线性筛素数 题目描述 如题,给定一个范围N,你需要处理M个某数字是否为质数的询问(每个数字均在范围1-N内) 输入输出格式 输入格式: 第一行包含两个正整数N.M,分别表示查询的范围和查询的个数. 接下来M行每行包含一个不小于1且不大于N的整数,即询问概数是否为质数. 输出格式: 输出包含M行,每行为Yes或No,即依次为每一个询问的结果. 输入输出样例 输入样例#1: 100 5 2 3 4 91 97 输出样例#1: Yes Yes No No Yes 说明 时空限制:5

筛素数

整理一下筛素数的方法 我在网上了解到两种筛素数的方法 一种是  1/3n*判断  的时间复杂度 一种是的时间复杂度应该是比这个低 先说一下第一种的思路 首先:一个数如果他除以一个素数除不尽,那么他除以该素数的倍数也除不尽 所以我们可以这么考虑 如果一个数是二或三的倍数 那么它一定不是素数 于是 对于  1 2 3 4 5 6 7 8 9 10 11 12…… 那么排除2和3的倍数 剩下的是 1 5 7 11 …… 对于六个数 6*n   6*n+1   6*n+2   6*n + 3   6*n