hdu4710Balls Rearrangement

来源:互联网 发布:201年10月淘宝申请小号 编辑:程序博客网 时间:2024/05/22 08:18

Balls Rearrangement

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 247    Accepted Submission(s): 124


Problem Description
Bob has N balls and A boxes. He numbers the balls from 0 to N-1, and numbers the boxes from 0 to A-1. To find the balls easily, he puts the ball numbered x into the box numbered a if x = a mod A.
Some day Bob buys B new boxes, and he wants to rearrange the balls from the old boxes to the new boxes. The new boxes are numbered from 0 to B-1. After the rearrangement, the ball numbered x should be in the box number b if x = b mod B.
This work may be very boring, so he wants to know the cost before the rearrangement. If he moves a ball from the old box numbered a to the new box numbered b, the cost he considered would be |a-b|. The total cost is the sum of the cost to move every ball, and it is what Bob is interested in now.
 

Input
The first line of the input is an integer T, the number of test cases.(0<T<=50)
Then T test case followed. The only line of each test case are three integers N, A and B.(1<=N<=1000000000, 1<=A,B<=100000).
 

Output
For each test case, output the total cost.
 

Sample Input
31000000000 1 18 2 411 5 3
 

Sample Output
0816
 

Source
2013 ACM/ICPC Asia Regional Online —— Warmup
 

Recommend
liuyiding
 

老实说我做这道题时,想到了a跟b的最小公倍数是他们的周期。。。
只要遍历一次周期就行了、、
不过后来想了一下还是不行。。。
因为a跟b的最小公倍数可以是100000*99999 。。。
这绝对会超时的,后来没有想出什么有效的方法就放下来了。。。
后来这网上找到一位高手的题解才知道我只想出了一半,还有一半是查找他们的公共部分。。
因为公共部分的差值是相同的orz。
还要注意是数据很大要用64位来存。。
#include <cstdio>  #include <cstring>  #include <algorithm>  #include <iostream>  #include<cmath>using namespace std;  __int64 Abs(__int64 a,__int64 b){return a>b?(a-b):(b-a);}__int64 max(__int64 a,__int64 b){if(a>b)return a;else return b;}__int64 min(__int64 a,__int64 b){if(a>b)return b;else return a;}__int64 work(__int64 n,__int64 a,__int64 b){__int64 now = 0,tmp,sum=0,x=0,y=0;//x和y是A箱序列和B箱序列结束部分的位置while(now < n){tmp = min(a-x,b-y);if(tmp+now > n)tmp = n-now;sum+=tmp*Abs(x,y);now+= tmp;x = (tmp+x)%a;y = (tmp+y)%b;}return sum;}__int64 LCM(__int64 a, __int64 b)//最小公倍数 {      __int64 aa = max(a, b);      __int64 bb = min(a, b);      do {          __int64 r = aa % bb;          aa = bb;          bb = r;      }while(bb);      return a * b / aa;  }  int main(){ __int64 num;__int64 n,a,b,G,k,k1;__int64 sum;scanf("%I64d",&num);while(num--){sum=0;scanf("%I64d%I64d%I64d",&n,&a,&b);G=LCM(a,b);if(G>=n){printf("%I64d\n",work(n,a,b));}else {k=n/G;    k1=n%G;printf("%I64d\n",k*work(G,a,b)+work(k1,a,b));}}return 0;}



原创粉丝点击