玲珑杯round#11 ----A

有一批n个数据需要通过rpc调用获取信息,为了加快速度,我们想要把n个数据平均分成若干份,每份的数据量为x(x可以整除n),假设一次rpc调用所需要的时间为a+b*x^2(其中a、b为常数),那么当给出a、b和n的时候,请求出一个x使得总时间最少,若有多个x满足,请输出最小的x。

INPUT
输入数据包含多组数据(<=15)。每一组只有一行三个整数a、b(1 <= a, b <= 10^6)和n(1 <= n <= 10 ^ 6)
OUTPUT
每组数据输出一行一个数,题目要求的x。
SAMPLE INPUT
2 2 32 1 3
SAMPLE OUTPUT
11

这道题用暴力就可以过,但是在这里还是要说一种更省时间的方法不至于以后暴力过不去,拿这题没办法

都能知道 这道题把函数列出来就是

y=b*n*x+a*n/x

是不是很熟悉,对,就是中学的对勾函数

当a>0,b>0时 对勾函数的最小值在√b/a 处最小值

但是这个最小值不一定是整数,也不一定整除n 

那么就要向两边找,找到符合条件的比较一下那个比较近

那么这个就是要找的X

还有要注意一点 

要用long long 不用就WA

虽然输入的数据用不着longlong 但是根据函数计算出来的结果可能int是存不下的

#include<stdio.h>
#include<math.h>
int main()
{
    long long a,b,n;
    while(scanf("%lld%lld%lld",&a,&b,&n)!=EOF)
    {
        long long k,l;
        k=sqrt(a/b),l=sqrt(a/b);
        if(k<1)
        {
            printf("1\n");
            continue;
        }
        while(l>0)
        {
            if(l==1)
            {
                break;
            }
            else if(n%l==0)
            {
                break;
            }
            else
            {
                l--;
            }
        }
        k++;
        while(k<=n)
        {
            if(n%k==0)
            {
                break;
            }
            if(n%k!=0)
            {
                k++;
            }
        }
        /*printf("%d %d\n",l,k);
        printf("%d %d\n",b*n*l+(a*n)/l,b*n*k+(a*n)/k);*/
      if(b*n*l+(a*n)/l<=b*n*k+(a*n)/k)
      {
          printf("%lld\n",l);
      }
      else
      {
          printf("%lld\n",k);
      }
    }
    return 0;
}









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值