UVA12558 Egyptian Fractions (HARD version)

算法竞赛
编辑文章

做完了ybt上的那道埃及分数,以为这道题只需要改一下就能过,结果断断续续折腾了一天多,我还是太菜了。

这道题与ybt那道主要区别就是多组数据+给定不能用的数。多组数据容易搞定,但处理不能用的数就把我坑惨了。

我最开始是直接拿bool数组来记录,然后次次本机AC,提交RE,调试发现是越界了。虽然答案不会很大,但由于是从小到大枚举,最开始最后一个就会很大而越界。

然后我就用了个数组,排序后用来判断,然后就WA了,看了题解才发现我并没有给判断最后一个,而很显然最后一次得到的数不一定满足单调性。最后我干脆就直接用set,然而因为忘了clear()又WA了几发才终于A掉了。

ll A,B,cur[1005],ans[1005],mn,k,t,kase,cnt;
set <ll> s;

bool better(int mx)
{
    for(int i=mx;i>=0;i--)
    {
        if(ans[i]==cur[i]) continue;
        return ans[i]==-1 || cur[i]<ans[i]; 
    }
    return 0;
}

ll gcd(ll x,ll y)
{
    return y ? gcd(y,x%y) : x;
}

void dfs(ll x,ll a,ll b,ll n,ll last)
{
    if (x==n)
    {
        if (b%a) return;
        b/=a;
        if (s.count(b)) return;
        cur[x]=b;
        if (better(n))
        {
            mn=b;
            memcpy(ans,cur,sizeof(ll)*(n+1));
        }
        return;
    }
    last++;
    last=max(last,b/a+1);
    for (;last<mn;last++)
    {
        if (a*last>=b*(n-x+1)) break;
        if (s.count(last)) continue;
        cur[x]=last;
        ll g=gcd(a*last-b,b*last);
        dfs(x+1,(a*last-b)/g,(b*last)/g,n,last);
    }
    return;
}

int main()
{
    t=read();
    while (t--)
    {
        s.clear();
        A=read(); B=read(); k=read();
        for (ll i=1;i<=k;i++) s.insert(read());
        printf("Case %lld: %lld/%lld=",++kase,A,B);
        ll i=1;
        for (;;)
        {
            cnt=1; mn=1e18;
            memset(ans,-1,sizeof(ans));
            dfs(1,A,B,i,0);
            if (mn<1e18) break;
            i++;
        }
        for (ll j=1;j<i;j++) printf("1/%lld+",ans[j]);
        printf("1/%lld\n",ans[i]);
    }
    return 0;
}

新评论

称呼不能为空
邮箱格式不合法
网站格式不合法
内容不能为空
    duanyll
    2019-03-20 22:54

    orz数论之神!

      Llf0703
      2019-03-21 12:40

      那啥,这道题是搜索啊跟数论有什么关系。

      这体现了您fAKe的本性,果然是大佬。