zoukankan      html  css  js  c++  java
  • UVA-12558 Egyptian Fractions (HARD version) (IDA* 或 迭代加深搜索)

    题目大意:经典的埃及分数问题。

    代码如下:

    # include<iostream>
    # include<cstdio>
    # include<cstring>
    # include<algorithm>
    using namespace std;
    # define LL long long
    
    int num[5],a,b,k;
    LL ans[10000],v[10000];
    
    LL gcd(LL a,LL b)
    {
        return (b==0)?a:gcd(b,a%b);
    }
    int get_first(LL a,LL b)
    {
        return b/a+1;
    }
    bool judge(int val)
    {
        for(int i=0;i<k;++i)
            if(val==num[i])
                return false;
        return true;
    }
    bool better(int d)
    {
        for(int i=d;i>=0;--i)
            if(ans[i]!=v[i])
                return ans[i]==-1||v[i]<ans[i];
        return false;
    }
    bool dfs(int cur,int maxd,int from,LL aa,LL bb)
    {
        if(cur==maxd){
            if(bb%aa)
                return false;
            v[cur]=bb/aa;
            if(!judge(v[cur]))
                return false;
            if(better(cur)){
                for(int i=0;i<=cur;++i)
                    ans[i]=v[i];
            }
            return true;
        }
        bool ok=false;
        from=max(from,get_first(aa,bb));
        for(int i=from;;++i){
            while(!judge(i))
                ++i;
            if(bb*(maxd-cur+1)<=i*aa)
                break;
            v[cur]=i;
            LL b2=bb*i;
            LL a2=aa*i-bb;
            LL g=gcd(a2,b2);
            if(dfs(cur+1,maxd,i+1,a2/g,b2/g))
                ok=true;
        }
        return ok;
    }
    void solve()
    {
        for(int maxd=1;;++maxd){
            memset(ans,-1,sizeof(ans));
            if(dfs(0,maxd,get_first(a,b),a,b)){
                printf("%d/%d=",a,b);
                for(int i=0;i<=maxd;++i)
                    printf("1/%lld%c",ans[i],(i==maxd)?'
    ':'+');
                break;
            }
        }
    }
    int main()
    {
        int T,cas=0;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d%d",&a,&b,&k);
            for(int i=0;i<k;++i)
                scanf("%d",num+i);
    
            printf("Case %d: ",++cas);
            solve();
        }
        return 0;
    }
    

      

  • 相关阅读:
    LeetCode 12. 整数转罗马数字
    [Python] for in range()使用以及列表字符串反转方法
    组合数问题
    「BJOI2020」封印
    数据结构优化建图
    小Q与找茬
    无旋Treap学习
    jzoj5679
    数星星
    凸性
  • 原文地址:https://www.cnblogs.com/20143605--pcx/p/4824313.html
Copyright © 2011-2022 走看看