杭电1239

这是一道极其简单的搜索题目,不过简单归简单,对于刚入门的人来说,再简单的搜不是那么简单。所以这里还是写一下,希望可以帮助别人。

题目的大意是:

na.给定整数m,a,b(4< m <= 100000 and

  1<= a <= b <= 1000)

nb.需要找到两个数(不妨设为p,q)满足以下条件:

      p,q均为质数;

    p*q<=m;

    a/b <= p/q <= 1;

c.输出所有满足以上条件的p,q中乘积最大的一对p,q。

典型的想法是

从所有可能的p,q中寻找满足条件的一对

n2.p,q的要求

p,q均为质数,且p<=q<=100000;

n3.按上述思想流程应为:

a.从1—100000中搜出质数

b.两层循环,试遍所有的组合(p,q可能相等)

c.每种组合去判断是否符合条件,如是,将p*q与当前最大值比较,判断,保存。

不过这样肯定是会超时的,因为p,q的范围很大,那么我们自然而然就会想到我们应该将范围适当的压缩,也算是剪枝吧。

以下两种方法:

(1)

p,q的范围其实可在2—50000(why?)
然而,这是最小的范围吗?
考虑大于10000的某个质数,不妨设为Q,另一个质数为P,则:
如果P<10,P/Q<0.001
如果P>10,P*Q>100000
而考虑到a,b的取值范围(1<=a<=b<=1000)
可知min(a/b)=0.001
同时,要求:p*q<=m<=100000
所以无论如何质数都不能超过10000
经过上面的数据的压缩,我们就可以直接来做了,首先找出10000以内的质数,应该不会超过2000,那么在这2000质数中采用暴力方法,一个一个搜索,最后求得最大的p*q;
(2),我们知道对于p<=100000,q<=100000;但是p*q<=100000,这就直接让我们想到了开方,就是p,q必有一个大于sqrt(100000),另一个小于sqrt(100000),那么这下范围就收缩了很多,再采用暴力方法来找出满足题意的p和q。
我用的是第二种方法,下面附上一个代码:
#include<iostream>
using namespace std;
#include<math.h>
int main()
{
    int m,a,b,p,q,j,max;
    int p1,q1;
    double k1,k2;
    int leap1,leap2;
    while(cin>>m>>a>>b,m||a||b)
    {
        leap1=0;
        leap2=0;
          max=j=0;
          k1=((double)a)/b;
          for(p=sqrt((double)m);p>=2;p--)
          {
              for(int i=2;i<=sqrt((double)p);i++)
              {
                   if(p%i==0)
                   {
                       leap1=1;
                       break;
                   }
                   else leap1=0;

              }
              if(leap1==0)
              { 
          for(q=p;q<=m/p;q++)
          {
              for(int t=2;t<=sqrt((double)q);t++)
              {
                 if(q%t==0)
                 {
                     leap2=1;
                     break;
                 }
                 else leap2=0;
              }
                 if(leap2==0)
                 {
                     k2=((double)p)/q;
                     if((k1<=k2)&&(k2<=1))
                     {
                         if(p*q>max)
                         {
                             p1=p;
                             q1=q;
                             max=p*q;
                         }
                     }
                 }

          }


              }

          }
          cout<<p1<<" "<<q1<<endl;
    }
    return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值