Problem 1097 Calling Extraterrestrial Intelligence Again.
题意
- extraterrestrial intelligence - 外星人
rectangular - 矩形的 - m > 4;0 < a/b < 1
area <= m
width 和 height 是素数,a/b <= width/height <=1
在以上限制下找到最大的area - 输入
三个数m,a,b(最多2000组),以0 0 0
结束
4 < m <= 100000 ,1 <= a <= b <= 1000 - 输出
area最大时的长宽(是素数)
思路
- 用筛法创建素数表,拿
100000 1 1000
去试,发现用到的最大素数是7691,所以只要创建8000以内的素数表即可 - 遍历素数表,对素数内元素乘积小于等于m最大值的所有情况,保存area及其较小的一个因子(即width)
- 对读入的每一组数据:
从m开始往前找,对每个<=m的area:
判断他的两个因子是否符合a/b <= width/height条件,找到第一个符合条件的area后跳出循环,输出
否则m–,直到找到下一个area,继续判断
笔记
- 复习了:筛法,二分查找
- 搜索一直一直超时怎么办:空间换时间
把答案列表,对每组输入查表
代码
#include<cstdio>
#include<cmath>
#include<string.h>
using namespace std;
int isPrime[100010];
int Primes[8000];
int len;
int ans[100010];
void creat_Primes(int x){
memset(isPrime, 1, sizeof(isPrime));
isPrime[0] = 0;
isPrime[1] = 0;
len = 0;
int i;
for(i=0; i<=x; i++){
if(isPrime[i]){
Primes[len++] = i;
for(int j=2*i; j<x; j+=i)
isPrime[j] = 0;
}
}
}
int main(){
int m, a, b;
int area;
int w, h;
creat_Primes(8000);
memset(ans, 0, sizeof(ans));
for(int i=0; i<len; i++){
for(int j=i; j<len; j++){
area = Primes[i]*Primes[j];
if(area<=100000)
ans[area] = Primes[i];
else
break;
}
}
while(scanf("%d%d%d", &m, &a, &b)!=EOF){
if(m==0 && a==0 && b==0)
break;
while(m){
if(ans[m]!=0){
w = ans[m];
h = m/ans[m];
if(a*1.0/b <= w*1.0/h)
break;
}
m--;
}
printf("%d %d\n", w, h);
}
return 0;
}