zoukankan      html  css  js  c++  java
  • 题目:埃及分数

    题目描述﹡﹡﹡﹡﹡

    在古埃及,人们使用单位分数的和(形如 1/a 的,a 是正整数)表示一切有理数。 
    如:2/3 = 1/2 + 1/6,但不允许 2/3 = 1/3 + 1/3,因为加数中有相同的。 
    对于一个分数 a/b ,表示方法有很多种,但是哪种最好呢? 
    首先,加数少的比加数多的好,其次,加数个数相同的,最小的分数越大越好。 
    如:

    19/45 = 1/3 + 1/12 + 1/180
    19/45 = 1/3 + 1/15 + 1/45
    19/45 = 1/3 + 1/18 + 1/30
    19/45 = 1/4 + 1/6 + 1/180
    19/45 = 1/5 + 1/6 + 1/18

    最好的是最后一种,因为 1/18 比 1/180、1/45、1/30、1/180 都要大。
    给出a、b (0 < a < b < 1000),试编程计算最好的表达方式。

    输入格式

    输入只有一行:a、b,表示需要表示的分数 a/b (0 < a < b < 1000)。

    输出格式

    一行,依次给出最好的表达方式中各个单位分数的分母(保证都在 32 位整型范围内)。

    迭代深化,但实现起来很难,而且RQ上数据还有问题。

    刚开始做的时候 函数传递的参数被我弄成浮点型,所以就game over了。

    别人的题解 函数传递的是除数于被除数。

    关键是剪枝。

    首先下一个分母一定比上一个大,所以所有的分母必须单调递增,所以1/分母 单调递减。

    若 tot 为后n 位 1/分母 的总和,则 tot/n 为后n 位 1/分母 的平均值,可知,当下的分母小于 平均值的倒数。

    所以 搜索的范围就求出来了。

    #include<iostream>
    using namespace std;
    
    long long a,b,g;
    int l,ans[100],best[100]; 
    bool p=0; 
    
    long long gcd(long long x,long long y){
         long long z; 
         while(x!=0)
         {z=x;x=y%x;y=z;} 
         return y; 
         } 
    
    void Dfs(long long x,long long y,int h){
         int i; 
         if(h==l) 
         {
          g=gcd(x,y);
          x/=g;y/=g; 
          if(x==1&&y>0&&y>ans[h-1]) 
          {
           if(p==0||(p==1&&y<best[h]))
           {
            for(i=1;i<h;++i) best[i]=ans[i];
            best[h]=y;p=1; return ;           
                   }             
                      } 
          return ; 
                  } 
         
         int mi=ans[h-1]+1,ma=(l-h+1)*y/x+2;
         long long xx,yy; 
         
         for(i=mi;i<=ma;++i)
         {
          ans[h]=i; 
          xx=x*i-y;yy=y*i;
          Dfs(xx,yy,h+1); 
                 } 
                 
         } 
    
    int main()
    {
        cin>>a>>b;
        g=gcd(a,b);
        a/=g;b/=g; 
        
        if(a==1) {cout<<b<<endl;return 0;} 
        
        for(l=2;;++l)
        {Dfs(a,b,1);if(p) break;} 
                    
        for(int i=1;i<l;++i)
        cout<<best[i]<<" ";
        cout<<best[l]<<endl; 
      //  system("pause");
        return 0; 
        } 
  • 相关阅读:
    maven学习讲解
    《Struts2.x权威指南》学习笔记2
    《Struts2.x权威指南》学习笔记1
    【转】Maven3把命令行创建的web工程转成Eclipse和IntelliJ Idea的工程
    [转]h5页面测试总结
    《零成本实现Web性能测试:基于Apache JMeter》读书笔记
    《软件性能测试过程详解与案例剖析》读书笔记
    手机屏幕尺寸测试——手机的实际显示页面的宽度
    web常识
    vue 生命周期
  • 原文地址:https://www.cnblogs.com/noip/p/2579877.html
Copyright © 2011-2022 走看看