码迷,mamicode.com
首页 > 编程语言 > 详细

【noi 2.7_413】Calling Extraterrestrial Intelligence Again(算法效率)

时间:2016-10-30 19:51:50      阅读:252      评论:0      收藏:0      [点我收藏+]

标签:语句   onclick   实现   ios   ash   false   color   break   分时   

题意:给3个数M,A,B,求两个质数P,Q。使其满足P*Q<=M且A/B<=P/Q<=1,并使P*Q最大。输入若干行以0,0,0结尾。

解法:先线性筛出素数表,再枚举出P,二分出对应的最大的Q,得出最佳答案。

注意——二分时通过pri[]的下标尽量大来实现,比递归快了很多,具体请见代码。

技术分享
 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<iostream>
 5 using namespace std;
 6 #define M 100010
 7 #define D 1010
 8 
 9 bool np[M/10];
10 int pri[M/20];
11 int cnt;
12 
13 int mmin(int x,int y) {return x<y?x:y;}
14 void init_pri()
15 {//1
16     cnt=0;
17     memset(np,false,sizeof(np));
18     for (int i=2;i<=M/10;i++)
19     {
20       if (!np[i]) pri[++cnt]=i;
21       for (int j=1;j<=cnt&&i*pri[j]<=M/10;j++)
22       {
23         np[i*pri[j]]=true;
24         if (i%pri[j]==0) break;//不能调到前一句前
25       }
26     }
27     /*2
28     cnt=0;
29     memset(np,false,sizeof(np));
30     for (int i=2;i<=M/10;i++)
31     {
32       if (np[i]) continue;
33       pri[++cnt]=i;
34       for (int j=2;i*j<=M/10;j++)
35         np[i*j]=true;
36     }
37     */
38 }
39 int main()
40 {
41     init_pri();
42     while (1)
43     {
44       int m,x,y;
45       scanf("%d%d%d",&m,&x,&y);
46       if (m+x+y==0) break;
47       int pp,qq; pp=qq=0;
48       for (int i=1;i<=cnt;i++)
49       {
50         int p=pri[i],lim=mmin(y*p/x,m/p);
51         int tmp=i;
52         for (int j=12;j>=0;j--)
53           if (tmp+(1<<j)<=cnt && pri[tmp+(1<<j)]<=lim) tmp+=(1<<j);
54         if (tmp==i && p*pri[tmp]>m) break;
55         int q=pri[tmp];
56         if (p*q>pp*qq) pp=p,qq=q;
57       }
58       printf("%d %d\n",pp,qq);
59     }
60     return 0;
61 }
View Code

而关于线性筛素数,我有2种方法。第一种是每得到一个素数,就让它乘1、2、3...,得到的数标记为不是素数;第二种是最常见的,也是比较快的,每个数都与已得到的素数相乘,得到的数也标记为不是素数,但要小心:当这个数是当前枚举的素数的倍数时,就要跳出循环了。而语句的顺序在理论上为什么在后面,我就不清楚了...O.O

我附上我的测试速度的代码吧,大家可以顺带学一下计时的方法~测出来方法一是0.02s,方法二是0.01s。

技术分享
 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<ctime>
 5 #include<iostream>
 6 using namespace std;
 7 #define M (int)1e6
 8 
 9 bool np[M];
10 int pri[M];
11 int cnt;
12 
13 int mmin(int x,int y) {return x<y?x:y;}
14 void init_pri()
15 {
16         cnt=0;
17         memset(np,false,sizeof(np));
18         for (int i=2;i<=M;i++)
19         {
20           if (np[i]) continue;
21           pri[++cnt]=i;
22           for (int j=2;i*j<=M;j++)
23                 np[i*j]=true;
24         }
25 }
26 int main()
27 {
28         init_pri();
29         printf("Time used=%.2lf\n",(double)clock()/CLOCKS_PER_SEC);
30         return 0;
31 }
View Code 1
技术分享
 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<ctime>
 5 #include<iostream>
 6 using namespace std;
 7 #define M (int)1e6
 8 
 9 bool np[M];
10 int pri[M];
11 int cnt;
12 
13 int mmin(int x,int y) {return x<y?x:y;}
14 void init_pri()
15 {
16         cnt=0;
17         memset(np,false,sizeof(np));
18         for (int i=2;i<=M;i++)
19         {
20           if (!np[i]) pri[++cnt]=i;
21           for (int j=1;j<=cnt&&i*pri[j]<=M;j++)
22           {
23                 np[i*pri[j]]=true;
24                 if (i%pri[j]==0) break;//hou
25           }
26         }
27 }
28 int main()
29 {
30         init_pri();
31         printf("Time used=%.2lf\n",(double)clock()/CLOCKS_PER_SEC);
32         return 0;
33 }
View Code 2

 

【noi 2.7_413】Calling Extraterrestrial Intelligence Again(算法效率)

标签:语句   onclick   实现   ios   ash   false   color   break   分时   

原文地址:http://www.cnblogs.com/konjak/p/6013713.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!