Egyptian Fractions (HARD version) UVA - 12558

埃及分数稍微加了一点限制条件,我是拿它作为埃及分数,IDA*算法的连习题来做的,结果也改了很长时间,是因为忘记了改成long long了

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn = 100;
int maxd;
set<int> ban;
ll v[maxn],ans[maxn];
ll gcd(ll a,ll b)
{
    if(!b) return a;
    return gcd(b,a%b);
}
ll getfirst(ll a,ll b)
{
    return b / a + 1;
}
bool better(int d)
{
    for(int i = d;i >= 0;i--)
    {
        if(v[i] != ans[i])
        return ans[i] == -1 || v[i] < ans[i];
    }
    return false;
}
bool dfs(int d,ll c,ll a,ll b)
{
    if(d == maxd)
    {
        if(b % a) return false;
        v[d] = b / a;
        if(ban.count(v[d])) return false;
        if(better(d)) memcpy(ans,v,sizeof(ll) * (d + 1));
        return true;
    }
    bool ok = false;
    c = max(c,getfirst(a,b));
    for(int p = c;;p++)
    {
        if(ban.count(p)) continue;
        if(b * (maxd + 1- d) <= a * p) break;
        v[d] = p;
        ll a1 = a * p - b;
        ll b1 = b * p;
        ll g = gcd(a1,b1);
        if(dfs(d + 1,p + 1,a1/g,b1/g)) ok = true;
    }
    return ok;
}
int main()
{
    int N; scanf("%d",&N);
    for(int kase = 1;kase <= N;kase++)
    {
        int a,b,k;
        ban.clear();
        scanf("%d%d%d",&a,&b,&k);
        for(int i = 1;i <= k;i++)
        {
            int x;
            scanf("%d",&x);
            ban.insert(x);
        }
        for(maxd = 1;;maxd++)
        {
            memset(v,-1,sizeof(v));
            memset(ans,-1,sizeof(ans));
            if(dfs(0,getfirst(a,b),a,b))
            {
                break;
            }
        }
        printf("Case %d: %d/%d=",kase,a,b);
        for(int i = 0;i <= maxd;i++)
        {
            if(i) printf("+");
            printf("1/%lld",ans[i]);
        }
        printf("\n");
    }
    return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值