标签:语句 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 }
而关于线性筛素数,我有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 }
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 }
【noi 2.7_413】Calling Extraterrestrial Intelligence Again(算法效率)
标签:语句 onclick 实现 ios ash false color break 分时
原文地址:http://www.cnblogs.com/konjak/p/6013713.html