Codeforces Round #184 (Div. 2) Continued Fractions 分数计算 long long相乘会越界

题目链接

关于分数的计算,真是很经典的问题

我开始用的重载运算符

错了 在于初始化和long long 相乘的越界

采用了第二种方法

#include<stdio.h>          //重载运算符 这道题不适用 *号和加号会越界
long long gcd(long long a,long long b){
    if(a%b==0)return b;
    else return gcd(b,a%b);
}

struct node{
     long long int deo,num;
     node(){}
     node(long long deo, long long num){
          if(num<0){
                deo=-deo;
                num=-num;    
          }
          long long div=gcd(deo,num);
          this->deo=deo/div;
          this->num=num/div;
     }       
     void set(long long deo,long long num){
          if(num<0){
                deo=-deo;
                num=-num;    
          }
          long long div=gcd(deo,num);
          this->deo=deo/div;
          this->num=num/div;     
     }
     node operator +(const node &a) const{
          return node(deo*a.num+a.deo*num,num*a.num);     
     }
     node operator /(const node &a) const{
          return node(deo*a.num,num*a.deo);     
     }
}a[300],ans,vec(1,1);

int main()
{
    long long one,two;
    while(scanf("%I64d %I64d",&one,&two)!=EOF){
         node ori(one,two);
         int n;
         long long dat;
         scanf("%d",&n);
         for(int i=1;i<=n;i++){
            scanf("%I64d",&dat);
            a[i].set(dat,1);     
         }
         if(n==1){
              if( (ori.deo==a[1].deo)&&(ori.num==a[1].num))printf("YES\n");
              else printf("NO\n");
              continue;         
         }
         ans=a[n];
         for(int i=n;i>=2;i--){
            ans=vec/ans;
            //printf("%I64d %I64d\n",ans.deo,ans.num); 
            ans=ans+a[i-1];   
            //printf("%I64d %I64d\n",ans.deo,ans.num);     
         }
         if( (ori.deo==ans.deo)&&(ori.num==ans.num))printf("YES\n");
         else printf("NO\n");
         
         
                       
    }
    return 0;    
}
利用题目的信息求解
#include<stdio.h>
#include<iostream>
#include<vector>
using namespace std;
#define ll  long long 
vector<ll> my;
int main()
{
    int n;
    ll up,down,dat;
    while(scanf("%I64d %I64d",&up,&down)!=EOF){
         my.clear();
         scanf("%d",&n);
         for(int i=1;i<=n;i++){    
             scanf("%I64d",&dat);
             my.push_back(dat);
         }
         bool judge=true;
         int i;
         for(i=0;i<my.size();i++){
                 if(up/down<my[i]){  //关键代码 避免了大数越界的情况
                 judge=false;
                 break;                  
                 }        
         //printf("%I64d %I64d\n",up,down);
         up=up-down*my[i];
         if(up==0)break;
         //printf("%I64d %I64d\n",up,down);
         if(i<my.size()-1)swap(up,down);
         //printf("%I64d %I64d\n",up,down);
         }
         if(up!=0)judge=false;
         if((up==0)&&(i!=my.size()-1))judge=false;
         if(judge==true)printf("YES\n");
         else printf("NO\n");
    }     
}

还有一种避免越界的情况

#include<stdio.h>
#include<iostream>
using namespace std;
#define ll long long
ll a[400]; 
int main()
{
    ll son,mon;
    while( scanf("%I64d %I64d",&son,&mon)!=EOF ){
         int n;
         scanf("%d",&n);
         for(int i=1;i<=n;i++)
            scanf("%I64d",&a[i]);
         int flag=1;
         for(int i=1;i<=n;i++){
            if(son<(double)mon*a[i]){ flag=0;break;}       //编程double相乘来避免  
            son=son-mon*a[i];
            swap(son,mon);
         }
         if( (flag==1) && (mon==0))puts("YES");
         else puts("NO");              
    }
    
    return 0;    
}






你可能感兴趣的:(算法)