给一个t,表示数据有多少组;
在给一个 m,A B;
m是 0到m-1个球,球号也是;
A是 体积为A的箱子,如果 如果 a==i%A 那么就把i球放到a箱子里
0<=a<=A-1;
B和A一样;
球每个球 的 sum+=abs(a-b);
在A箱子的箱号 减去B箱子的箱号的 绝对值,相加输出;
(1<=m<=1000000000, 1<=A,B<=100000)
真的好像c语言题。
但是数据特别大
用模拟的方法;
an 表示当前行(一行A个数)还有 多少空的位置。
并且发现 每一个球的差值其实是 A-B 或者是0
,所以直接计算最小比较的长度就行了。
还有要注意,len乘的是 au-bu;而不是a-b;
因为a-b永远有值,但是au-bu看处理情况而定。。。
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cmath>
//二分图的完全匹配问题。
//感觉自己的模拟水平还too young,too naive;
using namespace std;
long long solve(long long l,long long a,long long b)
{ //注意数据是到不了l的,因为是从0开始的。
long long au=0;
long long bu=0;
long long cnt=0;
long long ans=0;
long long len;
while(cnt<l)
{ len=min(a-au,b-bu);//未处理过的,谁占的次数最少。
if(len+cnt>=l) len=l-cnt;//如果超界就截取一下;
ans+=(long long )abs(au-bu)*len;
au+=len;
bu+=len;
if(au>=a) au-=a;
if(bu>=b) bu-=b;
cnt+=len;
}
return ans;
}
long long gcd(long long a,long long b)
{
if (b==0)
return a;
return gcd(b,a%b);
}
long long lcm(long long a,long long b)
{
long long c = gcd(a,b);
return a/c*b;
}
int main()
{ int T;
long long m,a,b;
scanf("%d",&T);
while(T--)
{ scanf("%lld%lld%lld",&m,&a,&b);
if(a==0&&b==0)
{printf("0\n");
continue;
}
long long n=lcm(a,b);
//printf("lcm %d\n",n);
if(m<n)
{
printf("%lld\n",solve(m,a,b));
continue;
}
else
{ long long l=m/n;
long long t=m%n;
//printf("%d %d**\n",l,t);
long long sum=solve(t,a,b)+solve(n,a,b)*l;
printf("%lld\n",sum);
continue;
}
//cout<<solve(m,a,b)<<endl;
}
return 0;
}