枚举法 POJ1411
給3個數 m ,a,b, 求兩個素數 c和d,
使得 c*d<=m a/b<=c/d<=1
其中m>4, a/b<=1
思路
窮舉素數 c(1,3,5,7,9,….m) c的窮舉范圍為(0,m)中所有的素數。
對于每一個窮舉的c,根據e=c*b/a,確定d的范圍為 (c,e)之間 的素數,
再在c確定的情況下,在d的范圍(c,e)之中尋找一個素數使得c*d的面積最大,并且c*d<=m;
通過程序
#include <math.h>
#include<iostream>
#include <algorithm>
#include <cstdio>
//判斷是否是質數
bool isPrime(int t)
{
int mid =(int)(sqrt((double)t));
for(int i=2;i<=mid;i++)
if(t%i==0)
return false;
return true;
}
/*
給3個數 m ,a,b, 求兩個素數 c和d,
使得 c*d<=m a/b<=c/d<=1
其中m>4, a/b<=1
第一次審題后的解法
窮舉素數 c(1,3,5,7,9,….m) c的窮舉范圍為(0,m)中所有的素數。
對于每一個窮舉的c,根據e=c*b/a,確定d的范圍為 (c,e)之間的素數,再在c確定的情況下,在d的范圍(c,e)之中尋找一個素數使得c*d的面積最大,并且c*d<=m;
枚舉的優化策略
改變枚舉次序
改變比較情況時所花的時間
剪枝--減少邊界條件的枚舉情況.
在本例中可以優化的地方為 確定p和q的取值范圍,
對于確定的m,p和q為質數,所以p和q最多取到sqrt(m);
因為m<=100000, sqrt(100000)=316.999,
所以p和q最多取到317
*/
int main(void)
{
int m,a,b,c,tt,temp,width,height;
double d,e,min;
long tempm,max;
while(1)
{
std::cin>>m>>a>>b;
if(m==0)break;
max=0;
/*
因為m的最大值為100000,所以可以確定在a=b的情況下,width和height的最大值最多為317,所以可以減少遍歷時間
*/
for(c=2;c<=317;c++)
{
if(isPrime(c)==true)
{
//e的取值為 min(m/c,c*b/a)
e=((double)c*b)/a;
min=m/c;
if(min<e)e=min;
for(tt=e;tt>=c;tt--) //確定c的范圍后在c到E之間找一個最大的質數,使其滿足條件c*tt<=m,對于tt為從大到小開始遍歷
{
if(isPrime(tt))
{
tempm=c*tt;
if(tempm<=m&&tempm>max)
{
width=c;
height=tt;
max=tempm;
break;
}
}
}
}
}
std::cout<<width<<" "<<height<<std::endl;
}
return 0;
}
轉載于:https://www.cnblogs.com/smile2you/archive/2010/03/10/1682963.html
總結
以上是生活随笔為你收集整理的枚举法 POJ1411的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: System.Net.Dns.GetHo
- 下一篇: office老是提示Microsoft