hdu 4710 Balls Rearrangement 数论

这个公倍数以后是循环的很容易找出来,然后循环以内的计算是打表找的规律,规律比较难表述,自己看代码吧。。

 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
long long n,a,b;
long long lcd(int a,int b)
{
    long long ret=a;
    ret*=b;
    int tmp;
    while(a%b)
    {
        tmp=a%b;
        a=b;
        b=tmp;
    }
    return ret/b;
}
long long cal(long long tmp)
{
//    cout<<tmp<<endl;
    long long sum=0,ret,i;
//    for(i=0;i<tmp;i++)
//    sum+=fabs(i%a-i%b);
//    return sum;
    for(i=0;i+a-1<tmp;i+=a)
    {
        ret=b-(i%b);
        if(ret>=a)
        sum+=(i%b)*a;
        else
        sum+=ret*(i%b)+(a-ret)*(b-(i%b));
    }
    for(;i<tmp;i++)
    sum+=fabs(i%a-i%b);
    return sum;
}
int main()
{
//    freopen("in.txt","r",stdin);
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%lld %lld %lld",&n,&a,&b);
        if(a>b) swap(a,b);
        long long m=lcd(a,b);
        long long ans=cal(m);
        ans*=n/m;
        ans+=cal(n%m);
        cout<<ans<<endl;
    }
    return 0;
}


 

 

posted @ 2013-09-09 20:28  pangbangb  阅读(143)  评论(0编辑  收藏  举报