您的位置:首页 > 其它

HDU 4611 Balls Rearrangement

2013-07-31 10:36 323 查看
思路:找到a和b的最小公倍数,这样两个数的余数就以最小公倍数为周期循环,在计算周期内的值时,同一段上升区间的差值是一样的,比如:对7取余的前几位是0,1,2,3,4,5;对3取余为0,1,2,0,1,2;那么对于前3位的上升序列来说他们的差值是一样的。

#include <cstdio>
#include <algorithm>
using namespace std;

typedef __int64 int64;

int64 Gcd(int64 a , int64 b)
{
while (b)
{
int64 temp = b;
b = a%b;
a = temp;
}
return a;
}

int64 Lcm(int64 a , int64 b)
{
return a/Gcd(a,b)*b;
}

int64 Abs(int64 k)
{
return k < 0 ? -k : k;
}

int64 Solve(int64 len , int64 a , int64 b)
{
int64 now = 0 , ret = 0 , nowa = 0 , nowb = 0;
while (now < len)
{
int64 temp = min(len-now,min(a-nowa,b-nowb));
ret += Abs(nowa-nowb)*temp;
nowa = (nowa+temp)%a;
nowb = (nowb+temp)%b;
now += temp;
}
return ret;
}

int main()
{
int t;
int64 n , a , b;
scanf("%d",&t);
while (t--)
{
scanf("%I64d%I64d%I64d",&n,&a,&b);
int64 lcm = Lcm(a,b);
if (n <= lcm)printf("%I64d\n",Solve(n,a,b));
else printf("%I64d\n",Solve(lcm,a,b)*(n/lcm)+Solve(n%lcm,a,b));//这里n/lcm没有打括号,wrong了一会儿,好苦逼
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: