玲珑杯round#11 ----A

来源:互联网 发布:pdf.js如何使用 编辑:程序博客网 时间:2024/05/01 02:22

有一批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
SOLUTION
“玲珑杯”ACM比赛 Round #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;}









0 0