您的位置:首页 > 其它

hdu 4611 Balls Rearrangement (13多校#2-A)

2013-08-03 19:21 141 查看
题目地址: http://acm.hdu.edu.cn/showproblem.php?pid=4611

题解:显然一个个求和时会以lcm(a,b)为周期,但是一旦a,b公因子比较少,这样也还是会超时的, i++这个跨度太小. 注意到如果mod a的序列在上升,mod b的序列也在上升,则ans+= 的那个值是不变的,这样我们就可以增加跨度了。 考虑从i开始的跨度为jump的序列时,只需要去 a-i%a ,b-i%b的较小值就可以了。 最后注意一下i+jump不可以超过边界,一旦超过,我们把i赋值成很大,这样保证会退出去就可以了

#include<iostream>
#include<cmath>
using namespace std;

typedef long long inta;

inta min(inta a,inta b)
{
if(a>b) return b;
else return a;
}
inta gcd(inta a,inta b)
{
if(b==0)  return a;
else return gcd(b,a%b);

}
inta lcm(inta a,inta b)
{
return a/gcd(a,b)*b;
}

inta cost(inta a,inta b,inta n)
{
inta ans=0;
for(int i=0;i<n;)
{
inta jump=min(a-i%a,b-i%b);

//  边界处理
if(i+jump>=n+1)
{
jump=n-i;
i=n;
}

ans+=(jump)*fabs(i%a-i%b);

//last=i;
i+=jump;
}
return ans;
}
int main()
{

int T;
cin>>T;
while(T--)
{
inta n,a,b;
cin>>n>>a>>b;

inta ans=0;
inta q=0;
if(n>=lcm(a,b))
{
q=n/lcm(a,b);

ans=q*cost(a,b,lcm(a,b));

}
ans+=cost(a,b,n-q*lcm(a,b));
cout<<ans<<endl;
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: