hdu 1239 Calling Extraterrestrial Intelligence Again

传送门

A message from humans to extraterrestrial intelligence was sent through the Arecibo radio telescope in Puerto Rico on the afternoon of Saturday November 16, 1974. The message consisted of 1679 bits and was meant to be translated to a rectangular picture with 23 * 73 pixels. Since both 23 and 73 are prime numbers, 23 * 73 is the unique possible size of the translated rectangular picture each edge of which is longer than 1 pixel. Of course, there was no guarantee that the receivers would try to translate the message to a rectangular picture. Even if they would, they might put the pixels into the rectangle incorrectly. The senders of the Arecibo message were optimistic.
We are planning a similar project. Your task in the project is to find the most suitable width and height of the translated rectangular picture. The term "most suitable" is defined as follows. An integer m greater than 4 is given. A positive fraction a / b less than or equal to 1 is also given. The area of the picture should not be greater than m. Both of the width and the height of the translated picture should be prime numbers. The ratio of the width to the height should not be less than a / b nor greater than 1. You should maximize the area of the picture under these constraints.

In other words, you will receive an integer m and a fraction a / b. It holds that m > 4 and 0 < a / b < 1. You should find the pair of prime numbers p, q such that pq <= m and a / b <= p / q <= 1, and furthermore, the product pq takes the maximum value among such pairs of two prime numbers. You should report p and q as the "most suitable" width and height of the translated picture.

Input

The input is a sequence of at most 2000 triplets of positive integers, delimited by a space character in between. Each line contains a single triplet. The sequence is followed by a triplet of zeros, 0 0 0, which indicated the end of the input and should not be treated as data to be processed.

The integers of each input triplet are the integer m, the numerator a, and the denominator b described above, in this order. You may assume 4 < m <= 100000 and 1 <= a <= b <= 1000.

Output

The output is a sequence of pairs of positive integers. The i-th output pair corresponds to the i-th input triplet. The integers of each output pair are the width p and the height q described above, in this order.

Each output line contains a single pair. A space character is put between the integers as a delimiter. No other characters should appear in the output.

Sample Input

5 1 2
99999 999 999
1680 5 16
1970 1 1
2002 4 11
0 0 0

Sample Output

2 2
313 313
23 73
43 43
37 53

【题意】

给你三个数a,b,c.让你找两个质数使得prime1和prime2,使得:

prime1*prime2<=a
b/c<=prime1/prime2<=1

如果有多对数字满足解,就输出pirme1*prime2最大的。

【分析】

显然质数表是要打出来的,然后我们发现[1,50000]只有不到6000个质数,为什么我们选择1-50000而非数据量中的1-100000呢,因为是两个质数的积,所以第一个质数最小为2,所以第二个质数是不会超过50000的,所以我们只用打出1-50000的。然后我们可以发现,6000个质数是可以枚举的。但是效率不是很高,我们可以根据prime的单调性可以知道的是我们枚举一个质数,然后二分的找第二个质数,这样显然是比较优的。但是第二个质数的范围怎么确定呢?

我们可以显然的知道根据题目的两个不等式可以显然得到:

prime1*b/c>=prime2
a/prime1>=prime2

这是第二个质数的两个上界。然后我们对这两个上届取一个最小值然后二分寻找最大的符合要求的prime2就是对应的答案。

【代码】

#include <iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<cmath>
#include<map>
#include<time.h>
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
bool nouse[50000];
int prime[6000];
int flag;
void init()
{
    flag = 0;
    memset(nouse,false,sizeof(nouse));
    for(int i = 2; i<50000; i++)
        if(!nouse[i])
        {
            prime[flag++] = i;
            for(int j = i*2; j<50000; j+=i)
                nouse[j] = true;
        }
}
int main()
{
//    freopen("in.txt","r",stdin);
    init();
    int a,b,c;
    while(cin>>a>>b>>c,a||b||c)
    {
        int ans = 0;
        int ans1,ans2;
        for(int i = 0;i<flag;i++)
        {
            if(prime[i]*prime[i]>a) break;
            int maxm = min(a/prime[i],prime[i]*c/b);
            if(maxm<prime[i]) continue;
            maxm = prime[upper_bound(prime,prime+flag,maxm)-prime-1];
            if(maxm*prime[i]>ans)
            {
                ans = maxm*prime[i];
                ans1 = prime[i];
                ans2 = maxm;
            }
        }
        printf("%d %d\n",ans1,ans2);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/mengzhongsharen/article/details/79328037