HDU 4710题解

来源:互联网 发布:烈火软件 编辑:程序博客网 时间:2024/04/29 11:59

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4710

题目思路:

找到最小公倍数后,以最小公倍数为最小单位来计算时,可能会出现这种状况:最下公倍数很大,然后就和没有优化以前没有什么区别啦,

每段最小公倍数内的也可以优化一下:

cal函数中,temp用来记录每次需要往前挪的位数,用now来记录计算到的地方,x用来记录循环到了0--a-1中的位置,y用来记录循环到了0--b-1

的位置,由于x位置处的值就为x,y位置的值就为y;因而,此时x,y位置的值的差就为下标x,y的差值了。

AC代码如下:

#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>#include<cmath>using namespace std;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){    return a/gcd(a,b)*b;}long long cal(long long n,long long a,long long b){    long long now=0,temp=0,x=0,y=0,ans=0;    while(now<n){        temp=min(a-x,b-y);        if(now+temp>=n)            temp=n-now;        ans+=temp*(abs(x-y));        x=(x+temp)%a;        y=(y+temp)%b;        now+=temp;    }return ans;}int main(){    long long T,N,A,B;    cin>>T;    while(T--){        cin>>N>>A>>B;        long long l=lcm(A,B);        if(l>=N) cout<<cal(N,A,B)<<endl;        else cout<<cal(l,A,B)*(N/l)+cal(N%l,A,B)<<endl;    }return 0;}