1 题面
http://acm.hdu.edu.cn/showproblem.php?pid=4710
2 题意
有n个球,编号为1~n-1,原先有n个盒子,编号为i的球会放在编号为(i)MOD(a)的盒子里,现在要将这些球按照(i)MOD(b)的规则放在b个盒子里,设一个球原先的坐标是pa,后来的坐标是pb则,移动这个球的代价为abs(pa - pb).
求总的消耗是多少.
3 思路
计算消耗时,往往连续的一段会有相同的代价,计算好一段段地跳着来算总代价可以提高效率.
4 代码
/*****************************************************************
> File Name: Cpp_Acm.cpp
> Author: Uncle_Sugar
> Mail: uncle_sugar@qq.com
> Created Time: 2016年05月17日 星期二 13时33分33秒
*****************************************************************/
# include <cstdio>
# include <cstring>
# include <cctype>
# include <cmath>
# include <cstdlib>
# include <climits>
# include <iostream>
# include <iomanip>
# include <set>
# include <map>
# include <vector>
# include <stack>
# include <queue>
# include <algorithm>
using namespace std;
const int debug = 1;
const int size = 100000 + 10;
const int INF = INT_MAX>>1;
typedef long long ll;
typedef pair<ll,ll> pir;
int main()
{
std::ios::sync_with_stdio(false);cin.tie(0);
ll i,j;
ll T;
cin >> T;
while (T--){
ll n,a,b;
cin >> n >> a >> b;
if (a==b){
cout << 0 << endl;
continue;
}
if (a>b) swap(a,b);
ll lcm = a/__gcd(a,b)*b;
ll t = n/lcm,r = n%lcm;
ll tans = 0, rans = 0;;
ll posa = 0, posb = 0;
ll sum = 0;
do{
ll s = max(posa,posb);
ll e = min(posa+a,posb+b);
if (e >= r && r >= s){
rans = sum + abs(s%a - s%b)*(r - s);
}
sum += abs(s%a - s%b)*(e - s);
if (e==posb+b) posb = e;
else posa = e;
}while (posa!=posb);
tans = sum*t + rans;
cout << tans << endl;
}
return 0;
}