http://blog.csdn.net/dyx404514/article/details/9474251
上面的那个很好的解释了。
以11 5 3 为例 5 3 的最小公倍数15
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 放进a箱子 i%5的值以5为循环
0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 放进b箱子 i%3的值以3为循环
0 0 0 3 3 2 1 1 1 4 1 1 2 2 2 从他们的cost找出规律:发现cost值是 相等的区间最左端对应的上方都是0。
#include<iostream>
#include<cstdio>
using namespace std;
#define LL __int64
LL gcd(LL a,LL b)
{
LL r;
while(b)
{
r=a%b;
a=b;
b=r;
}
return a;
}
LL min(LL a,LL b)
{
if(a<b)
return a;
return b;
}
int main()
{
int t;
cin>>t;
while(t--)
{
LL n,a,b;
LL ans=0;
LL temp=0;
cin>>n>>a>>b;
LL lcm=a/gcd(a,b)*b;
LL m=n/lcm;
LL k=n%lcm;
for(LL i=0;i<lcm;)
if(i%a==i%b)
i+=min(a-i%a,b-i%b);
else
{
temp+=abs(i%a-i%b)*min(a-i%a,b-i%b);
i+=min(a-i%a,b-i%b);
}
for(LL i=0;i<k;)
if(i%a==i%b)
i+=min(a-i%a,b-i%b);
else
{
ans+=abs(i%a-i%b)*min(min(a-i%a,b-i%b),k-i);
i+=min(min(a-i%a,b-i%b),k-i);
}
ans+=temp*m;
cout<<ans<<endl;
}
return 0;
}