简单模拟题。只要理解了题意,基本上都写得出的。
思路1:首先知道求的是素数,那么通过筛选法打表。由于p/q<=1 --> p <= sqrt(m); a/b <= p/q --> a*q <= b*p;p*q的值要最大,那么就枚举所有的值那么就可以求出正确的数字啦。(优化过的代码,顺便复习下最基础的东西,其实直接枚举也可以过的~)
CODE:
#include <stdio.h>
#include <stdlib.h>
#include < string.h>
#include <math.h>
using namespace std;
const int maxn = 1200; // sqrt(100000);
int prime[maxn];
int vis[maxn];
int tot;
void init() // 素数打表
{
int i, j;
tot = 0;
memset(vis, 0, sizeof(vis));
for(i = 2 ; i < maxn ; i++) if(!vis[i])
{
prime[tot++] = i;
for(j = i*i; j < maxn; j+=i) vis[j] = 1;
}
return ;
}
int bsearch( int v) // 2分查找离p最近的值
{
int l = 0, h = tot- 1;
while(l < h)
{
int m = (l+h)/ 2;
if(prime[m] == v) return prime[m];
else if(prime[m] > v) h = m- 1;
else l = m+ 1;
}
return prime[h- 1];
}
int main()
{
int m, a, b;
int p, q, index;
init();
while(~scanf( " %d%d%d ", &m, &a, &b), m, a, b)
{
int i, j;
index = 0;
int index = bsearch(( int)sqrt(m));
int max = - 1;
for(i = index ; i >= 0 ; i--) // p
{
for(j = tot- 1; j >= i; j--) // q
{
if(b*prime[i] >= a*prime[j] && prime[i]*prime[j] <= m)
{
if(prime[i]*prime[j] > max)
{
p = prime[i];
q = prime[j];
max = prime[i]*prime[j];
}
}
}
}
printf( " %d %d\n ", p, q);
}
return 0;
#include <stdlib.h>
#include < string.h>
#include <math.h>
using namespace std;
const int maxn = 1200; // sqrt(100000);
int prime[maxn];
int vis[maxn];
int tot;
void init() // 素数打表
{
int i, j;
tot = 0;
memset(vis, 0, sizeof(vis));
for(i = 2 ; i < maxn ; i++) if(!vis[i])
{
prime[tot++] = i;
for(j = i*i; j < maxn; j+=i) vis[j] = 1;
}
return ;
}
int bsearch( int v) // 2分查找离p最近的值
{
int l = 0, h = tot- 1;
while(l < h)
{
int m = (l+h)/ 2;
if(prime[m] == v) return prime[m];
else if(prime[m] > v) h = m- 1;
else l = m+ 1;
}
return prime[h- 1];
}
int main()
{
int m, a, b;
int p, q, index;
init();
while(~scanf( " %d%d%d ", &m, &a, &b), m, a, b)
{
int i, j;
index = 0;
int index = bsearch(( int)sqrt(m));
int max = - 1;
for(i = index ; i >= 0 ; i--) // p
{
for(j = tot- 1; j >= i; j--) // q
{
if(b*prime[i] >= a*prime[j] && prime[i]*prime[j] <= m)
{
if(prime[i]*prime[j] > max)
{
p = prime[i];
q = prime[j];
max = prime[i]*prime[j];
}
}
}
}
printf( " %d %d\n ", p, q);
}
return 0;
}
思路2: 后来想了想,其实不需要知道p <= sqrt(m)。只需知道p <= q就行了,然后一个一个的枚举。也过了,哈哈~
CODE:
#include <stdio.h>
#include <stdlib.h>
#include < string.h>
#include <math.h>
using namespace std;
const int maxn = 1200; // sqrt(100000);
int prime[maxn];
int vis[maxn];
int tot;
void init() // 素数打表
{
int i, j;
tot = 0;
memset(vis, 0, sizeof(vis));
for(i = 2 ; i < maxn ; i++) if(!vis[i])
{
prime[tot++] = i;
for(j = i*i; j < maxn; j+=i) vis[j] = 1;
}
return ;
}
int main()
{
int m, a, b;
int p, q, index;
init();
while(~scanf( " %d%d%d ", &m, &a, &b), m, a, b)
{
int i, j;
int max = - 1;
for(i = tot- 1 ; i >= 0 ; i--) // q
{
for(j = i; j >= 0; j--) // p
{
if(a*prime[i] <= b*prime[j] && prime[i]*prime[j] <= m)
{
if(prime[i]*prime[j] > max)
{
q = prime[i];
p = prime[j];
max = prime[i]*prime[j];
}
}
}
}
printf( " %d %d\n ", p, q);
}
return 0;
#include <stdlib.h>
#include < string.h>
#include <math.h>
using namespace std;
const int maxn = 1200; // sqrt(100000);
int prime[maxn];
int vis[maxn];
int tot;
void init() // 素数打表
{
int i, j;
tot = 0;
memset(vis, 0, sizeof(vis));
for(i = 2 ; i < maxn ; i++) if(!vis[i])
{
prime[tot++] = i;
for(j = i*i; j < maxn; j+=i) vis[j] = 1;
}
return ;
}
int main()
{
int m, a, b;
int p, q, index;
init();
while(~scanf( " %d%d%d ", &m, &a, &b), m, a, b)
{
int i, j;
int max = - 1;
for(i = tot- 1 ; i >= 0 ; i--) // q
{
for(j = i; j >= 0; j--) // p
{
if(a*prime[i] <= b*prime[j] && prime[i]*prime[j] <= m)
{
if(prime[i]*prime[j] > max)
{
q = prime[i];
p = prime[j];
max = prime[i]*prime[j];
}
}
}
}
printf( " %d %d\n ", p, q);
}
return 0;
}