POJ3101 大数+LCM

不是很难,倒是写大数类用了很久,由于要考虑到中间过程会出现long long 的情况,大数类里面的东西要用long long 写,包括,除法,取模运算什么的。

N个分数的的最小公倍数是分子的最小公倍数,分母的最大公约数。

(1/2)/(1/t1-1/t2)得到时间间隔,化简得到t1*t2/(2*(t2-t1))

#include <string.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
#define NNN cout<<'\n';
using namespace std;
long long a[1111],b[1111];
long long que=0;
long long absMy(long long aa)
{
    if(aa<0)
        return -aa;
    else
        return aa;
}
class BigInteger
{
public:
    long long num[1000];
    long long len;

    BigInteger()
    {
        len=0;
        memset(num,0,sizeof(num));
    }

    BigInteger(char* ss)
    {
        len=0;
        memset(num,0,sizeof(num));
        long long& i=this->len;
        long long lenofss=strlen(ss);
        char s[10]={0};
        for(i=0;lenofss/4;lenofss-=4)
        {
            strncpy(s,ss+lenofss-4,4);
            this->num[i++]=atoi(s);
        }
        if(lenofss)
        {
            memset(s,0,sizeof(s));
            strncpy(s,ss,lenofss);
            this->num[i++]=atoi(s);
        }
    }

	BigInteger(long long s)
	{
		len=0;
		memset(num,0,sizeof(num));
		while(s>10000)
		{
			num[len++]=s%10000;
			s/=10000;
		}
		if(s)
		{
			num[len++]=s;
		}
		if(s==0)
            len=1;
	}

    void Print()
    {
        long long i;
        printf("%lld",num[len-1]);
        for(i=this->len-2;i>=0;i--)
        {
            printf("%04lld",this->num[i]);
        }
		//printf("\n");
    }

    BigInteger Times(BigInteger sec)//该数本身没有变化,只是返回了结果
    {
        long long i,j,jw;
        BigInteger ans;
        for(i=0;i<len;i++)
        {
            jw=0;
            ans.len=i;
            for(j=0;j<sec.len;j++)
            {
                jw+=this->num[i]*sec.num[j]+ans.num[ans.len];
                ans.num[ans.len++]=jw%10000;
                jw/=10000;
            }
            while(jw)
            {
                jw+=ans.num[ans.len];
                ans.num[ans.len++]=jw%10000;
                jw/=10000;
            }
        }
        return ans;
    }

    BigInteger plusone()
    {
        long long i=0;
        do
        {
            num[i]++;
            num[i+1]+=num[i]/10000;
            num[i]%=10000;
            i++;
        }while(num[i]<9999);
        return *this;
    }

	BigInteger operator+(const BigInteger& sec)
	{
		bool isUp=false;
		BigInteger tmp=*this;
		for(long long i=0;i<this->len;i++)
		{
			if(isUp)
			{
				tmp.num[i]++;
				if(tmp.num[i]>=10000)
				{
					tmp.num[i]=0;
					isUp=true;
				}
			}
			if(tmp.num[i]+sec.num[i]<=9999)
			{
				tmp.num[i]+=sec.num[i];
				isUp=false;
			}
			else
			{
				tmp.num[i]=tmp.num[i]+sec.num[i]-10000;
				isUp=true;
			}
		}
		long long maxn=tmp.len>sec.len?tmp.len:sec.len;
		if(tmp.num[maxn]!=0)
            tmp.len++;
        else
            tmp.len=maxn;
		return tmp;
	}

	BigInteger operator-(const BigInteger& sec)//big-small
	{
		bool isBorrow=false;
		BigInteger tmp=*this;
		for(long long i=0;i<this->len;i++)
		{
			if(isBorrow)
			{
				tmp.num[i]-=1;
				if(tmp.num[i]<0)
					tmp.num[i]=9999;
			}
			if(tmp.num[i]<sec.num[i])
			{
				tmp.num[i]=tmp.num[i]+10000-sec.num[i];
				isBorrow=true;
			}
			else
			{
				tmp.num[i]-=sec.num[i];
				isBorrow=false;
			}
		}
		long long i=0;
		for(i=999;i>=0;i--)
        {
            if(tmp.num[i]!=0)
                break;
        }
        if(i==-1)
            tmp.len=1;
        else
            tmp.len=i+1;
		return tmp;
	}

    BigInteger operator*(const BigInteger sec)
    {
        return this->Times(sec);
    }

	BigInteger operator/(long long sec)//big/small
	{
	    /*if(sec==1)
            return *this;*/
        BigInteger ret;
        long long i,down=0;
		for(i=len-1;i>=0;i--)
        {
            ret.num[i]=(num[i]+down*10000)/sec;
            down=num[i]+down*10000-ret.num[i]*sec;
        }
        ret.len=len;
        while(ret.num[ret.len-1]==0&&ret.len>1)
            ret.len--;
        return ret;
	}

	BigInteger operator%(long long sec)
	{
		BigInteger tmp=*this;
		BigInteger shang=tmp/sec;
		BigInteger big_sec=BigInteger(sec);
		BigInteger ans=tmp-shang*big_sec;
		return ans;
	}

	BigInteger& operator++()
    {
        this->plusone();
        return *this;
    }

	bool operator<=(const BigInteger& sec)
	{
		if(len<sec.len)
			return true;
		for(long long i=len-1;i>=0;i--)
		{
			if(num[i]>sec.num[i])
				return false;
		}
		return true;
	}

	bool operator>=(const BigInteger& sec)
	{
		if(len>sec.len)
			return true;
		for(long long i=len-1;i>=0;i--)
		{
			if(num[i]<sec.num[i])
				return false;
		}
		return true;
	}

	bool operator==(const BigInteger& sec)
	{
		if(len!=sec.len)
			return false;
		for(long long i=len-1;i>=0;i--)
		{
			if(num[i]!=sec.num[i])
				return false;
		}
		return true;
	}

	bool operator==(const long long& sec)
	{
		if(len!=1)
			return false;
		if(num[0]==sec)
			return true;
		else
			return false;
	}

	bool operator<(const BigInteger& sec)
	{
		if(len<sec.len)
			return true;
		for(long long i=len-1;i>=0;i--)
		{
			if(num[i]>sec.num[i])
				return false;
			else if(num[i]<sec.num[i])
				return true;
		}
		return false;
	}

	bool operator>(const BigInteger& sec)
	{
		if(len>sec.len)
			return true;
		for(long long i=len-1;i>=0;i--)
		{
			if(num[i]<sec.num[i])
				return false;
			else if(num[i]>sec.num[i])
				return true;
		}
		return false;
	}

	bool operator!=(const BigInteger& sec)
	{
		if(len!=sec.len)
			return true;
		for(long long i=len-1;i>=0;i--)
		{
			if(num[i]!=sec.num[i])
				return true;
		}
		return false;
	}

	/*BigInteger GCD(const BigInteger& first,const BigInteger& sec)
	{
		return first%sec==0?sec:GCD(sec,first%sec);
	}

	BigInteger LCM(const BigInteger& first,const BigInteger& sec)
	{
		return first/GCD(first,sec)*sec;
	}*/
};
long long gcd(long long a,long long b)
{
    if(a<b)
        swap(a,b);
    return b==0?a:gcd(b,a%b);
}
long long lcm(long long a,long long b)
{
    return a/gcd(a,b)*b;
}
int main()
{
    //freopen("D:/1.txt","r",stdin);
	//freopen("D:/my.txt","w",stdout);
    long long n;
    long long first;
    cin>>n;
    for(long long i=0;i<n;i++)
    {
        long long time;
        cin>>time;
        if(!i)
            first=time;
        else if(first!=time)
        {
            long long tmp=gcd(first*time,2*absMy(first-time));
            a[que]=first*time/tmp;
            b[que++]=2*absMy(first-time)/tmp;
            first=time;
        }
    }

    if(que==1)
    {
        printf("%lld %lld\n",a[0],b[0]);
    }
    else
    {
        long long gcdnum;
        gcdnum=gcd(b[0],b[1]);
        for(long long i=2;i<que;i++)
        {
            gcdnum=gcd(gcdnum,b[i]);
        }
        long long ans2=gcdnum;
        BigInteger a0=BigInteger(a[0]);
        BigInteger a1=BigInteger(a[1]);
        BigInteger lcmnum=a0*a1/gcd(a[0],a[1]);
        BigInteger bigai;
        BigInteger modn_big;
        long long tmpgcd;
        for(long long i=2;i<que;i++)
        {
            modn_big=lcmnum%a[i];
            long long modn=modn_big.num[1]*10000+modn_big.num[0];
            tmpgcd=gcd(a[i],modn);
            bigai=BigInteger(a[i]);
            lcmnum=bigai*lcmnum/tmpgcd;
            /*cout<<"TMPGCDis: ";
            lcmnum.Print();
            NNN
            cout<<"lcmis: ";
            lcmnum.Print();
            NNN
            cout<<"lcmis: ";
            lcmnum.Print();
            NNN*/

        }
        lcmnum.Print();
        printf(" %lld\n",ans2);
    }

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值