题目链接http://acm.hdu.edu.cn/showproblem.php?pid=1239
【题目大意】
输入三个数,m,a,b
让你求出一对素数 p ,q ,且满足 p x q <=m && a/b <=p/q <= 1;
数据范围
4< m <= 100000 , 1 <= a <= b <= 1000.
【思路】
先用素数筛选法,将1--100000的素数筛选出来, 打了一下表 发现有9000+个素数;
直接暴力枚举将达到复杂度达到1e8,不行;
注意到 p/q <= 1;这个条件,如果我们用外层循环表示较小的p,里层循环表示q,那么q的循环将从p的值开始循环(因为p/q <= 1),因此 p*q的最小值为p*p;
所以,外层循环的p只要循环到sqrt(m)就可以啦,这样时间复杂度就大大降低了。
【源代码】
#include <iostream>
#include <math.h>
using namespace std;
const int maxn= 100000 +10;
bool prime[maxn];
int num[maxn];
int cnt=0;
void f_prime(){ //素数筛选
for(int i=2;i<maxn;i++){
if(!prime[i]){
num[cnt++]=i;
for(int j=i*2;j<maxn;j+=i){
prime[j]=1;
}
}
}
}
int main(){
int m;
double a,b;
f_prime();
while(cin>>m>>a>>b){
if(m==0&&a==0&&b==0) break;
int max=0,maxi=0,maxj=0;
for(int i=0;i<=sqrt(m);i++){ //p
for(int j=i;j<cnt-1;j++){ //q
double div=(double)num[i]/(double)num[j]-(a/b);
if(num[i]*num[j]<=m&&div>=0){
if(num[i]*num[j]>max){
max=num[i]*num[j];
maxi=num[i];
maxj=num[j];
}
}
}
}
cout<<maxi<<" "<<maxj<<endl;
}
return 0;
}