2010-1072

从 Trac 迁移的文章

这是从旧校内 Wiki 迁移的文章,可能存在一些样式问题,您可以向 memset0 反馈。

原文章内容如下:

题目的大意就是用分子为1的分数来逼近一个分数,分子为A,分母为B,逼近的各个分数前符号依次为正负,如果能在5项内取到A/B则输出各项分母,如果不能,输出Too complex。

因为要求的项数较少,所以可以采用深搜来做,利用等式 A/B = 1/i - (B-i*A)/B,枚举该层的i后把 B-i*A 和 B 继续深搜, 如果搜到 B%A==0 则停止深搜, 得到最小的top值。

以下是标程:

{{{
#!cpp
#include<cstdio>
#include<cstring>
using namespace std;
int top;
int ans[10];
int gcd(int n,int m)
{
    int r;
    while(m)
    {
        r = n%m;
        n = m;
        m = r;
    }
    return n;
}
bool dfs(int a,int b,int d)
{
    if(d>=top)
        return false;
    if(b%a==0)
    {
        ans[d] = b/a;
        return true;
    }
    int div = gcd(a,b);
    a /= div;
    b /= div;
    for (int i = 2; i*a<b; i++)
    if (dfs(b-i*a,b,d+1))
    {
        ans[d] = i;
        return true;
    }
    return false;
}
int main()
{
    int cas;
    scanf("%d",&cas);
    while(cas--)
    {
    int a,b;
    scanf("%d%d",&a,&b);
    for (top = 1; top<=5; ++top)
    {
        memset(ans,0,sizeof(ans));
        if( dfs(a,b,0)||dfs(b-a,b,0))
        {
            for (int i = 0; ans[i]!=0; i++)
                printf("%d%c",ans[i],ans[i+1]?' ':'\n');
                break;
        }
    }
    if(top>5)
        puts("Too complex");
    }
}
}}}
by forestkeeper

题目的大意就是用分子为1的分数来逼近一个分数,分子为A,分母为B,逼近的各个分数前符号依次为正负,如果能在5项内取到A/B则输出各项分母,如果不能,输出Too complex。

因为要求的项数较少,所以可以采用深搜来做,利用等式 A/B = 1/i - (B-i*A)/B,枚举该层的i后把 B-i*A 和 B 继续深搜, 如果搜到 B%A==0 则停止深搜, 得到最小的top值。

以下是标程:

#include<cstdio>
#include<cstring>
using namespace std;
int top;
int ans[10];
int gcd(int n,int m)
{
    int r;
    while(m)
    {
        r = n%m;
        n = m;
        m = r;
    }
    return n;
}
bool dfs(int a,int b,int d)
{
    if(d>=top)
        return false;
    if(b%a==0)
    {
        ans[d] = b/a;
        return true;
    }
    int div = gcd(a,b);
    a /= div;
    b /= div;
    for (int i = 2; i*a<b; i++)
    if (dfs(b-i*a,b,d+1))
    {
        ans[d] = i;
        return true;
    }
    return false;
}
int main()
{
    int cas;
    scanf("%d",&cas);
    while(cas--)
    {
    int a,b;
    scanf("%d%d",&a,&b);
    for (top = 1; top<=5; ++top)
    {
        memset(ans,0,sizeof(ans));
        if( dfs(a,b,0)||dfs(b-a,b,0))
        {
            for (int i = 0; ans[i]!=0; i++)
                printf("%d%c",ans[i],ans[i+1]?' ':'\n');
                break;
        }
    }
    if(top>5)
        puts("Too complex");
    }
}

by forestkeeper