zoukankan      html  css  js  c++  java
  • codevs1288 埃及分数

    题目描述:

    在古埃及,人们使用单位分数的和(形如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),编程计算最好的表达方式。

    题解:
    搜索。迭代加深搜索,也称IDDFS。

    搞一搞边界剪一剪枝。

    代码:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define ll long long
    ll a,b;
    ll ans[1000500],tmp[1000500];
    ll gcd(ll x,ll y)
    {
        if(!y)return x;
        return gcd(y,x%y);
    }
    ll aa,bb,Gcd,i,lim;
    void dfs(ll u,ll dep,ll la,ll lb)
    {
        if(dep==lim)
        {
            if(la==1&&u<=lb)
            {
                tmp[lim]=lb;
                if(lb<=ans[lim]||!ans[lim])
                {
                    for(i=1;i<=lim;i++)
                        ans[i]=tmp[i];
                }
            }
            return ;
        }
        if(u*la>lb*(lim-dep+1))return ;
        if(ans[lim]&&u>ans[lim])return ;
        dfs(u+1,dep,la,lb);
        tmp[dep]=u;
        aa = la*u-lb,bb = lb*u;
        if(aa<0)return ;
        Gcd = gcd(aa,bb);
        aa/=Gcd,bb/=Gcd;
        dfs(u+1,dep+1,aa,bb);
    }
    int main()
    {
        scanf("%lld%lld",&a,&b);
        Gcd = gcd(a,b);
        a/=Gcd,b/=Gcd;
        for(lim=1;;lim++)
        {
            dfs(b/a,1,a,b);
            if(ans[1])break;
        }
        for(i=1;ans[i];i++)
            printf("%lld ",ans[i]);
        printf("
    ");
        return 0;
    }
  • 相关阅读:
    easypoi添加下拉预选值
    java启动项目字符编码和配置文件的字符编码问题
    leetcode
    leetcode
    leetcode
    leetcode
    事务的隔离级别- 极客时间()
    数据库的事务
    SQL中的视图(极客时间)
    SQL中的连接(极客时间)
  • 原文地址:https://www.cnblogs.com/LiGuanlin1124/p/10003315.html
Copyright © 2011-2022 走看看