hdu 4710 Balls Rearrangement

  题意就不说了,刚开始做我竟然傻傻地去模拟,智商捉急啊~~超时是肯定的

  求出 a ,b 的最小公倍数,因为n够长的话,就会出现循环,所以就不要再做不必要的计算了。如果最小公倍数大于n的话,就直接计算n吧。

  除了可以应用循环来节省计算,还可以成段计算来节省。

#include<stdio.h>
#include<string.h>
#define i64 __int64

i64 abs(i64 x)
{
    if(x<0)
        return -x;
    return x;
}
i64 gcd(i64 a,i64 b)
{
    if(b==0)    return a;
    return gcd(b,a%b);
}
i64 Deal(i64 len,i64 a,i64 b)
{
    int i=0;
    i64 ans=0;
    while(i<len)
    {
        int tmp = (a-i%a)>(b-i%b)?(b-i%b):(a-i%a);
        if(tmp+i>len)
            tmp=len-i;
        ans+=abs(i%a-i%b)*tmp;
        i+=tmp;
    }
    return ans;
}
int main()
{
    i64 N,A,B;
    int T;
    i64 ans;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%I64d%I64d%I64d",&N,&A,&B);
        if(A==B)
        {
            printf("0\n");
            continue;
        }
        i64 tmp = A/gcd(A,B)*B;
        if(tmp>N)   ans=Deal(N,A,B);
        else    ans=Deal(tmp,A,B)*(N/tmp)+Deal(N%tmp,A,B);
        printf("%I64d\n",ans);
    }
    return 0;
}

 

posted @ 2013-09-08 22:12  yongren1zu  阅读(194)  评论(0编辑  收藏  举报