uva 10717 Mint

数学题:考查lcm和gcd

题意:输入n,m,表示有n种不同的硬币,m张桌子。下面n行是n种硬币的数值,接下来m行是每个桌子高度。每个桌子都固定有4个脚而且高度一样。用硬币来组成桌脚,要求一只脚要用一样的硬币。对于每个桌子输出两个数字,一个是小于等于该桌子高度的最大值,一个是大于等于桌子高度的最小值

 

就是枚举n个硬币中的4个,然后求4个硬币的最小公倍数,然后将这个lcm翻倍,只要满足 “一个是小于等于该桌子高度的最大值,一个是大于等于桌子高度的最小值”

 

#include <cstdio>
#include <cstring>
#define N 55
#define M 15
#define INF 0x3f3f3f3f
int num[5];  //枚举4个数字
int h[N];  //所有硬币
int t;  //桌子的高度
int n,m;
int LCM,L,R;

int gcd(int a ,int b)
{
    return b==0?a:gcd(b,a%b);
}
int lcm(int a ,int b)
{
    int tmp;
    if(a<b) 
    { tmp=a; a=b; b=tmp; }
    return a/gcd(a,b)*b;
}
void solve()
{
    LCM=num[0];
    for(int i=1; i<4; i++)
        LCM=lcm(LCM,num[i]);
    //printf("LCM=%d\n",LCM);
    int l,r,i;

    for(i=0; LCM*(i+1)<t; i++) ;

    if(LCM*(i+1)==t)
        l=r=LCM*(i+1);
    else
    {
        l=LCM*i;
        r=LCM*(i+1);
    }

    if(l>L) L=l;
    if(r<R) R=r;
}
void dfs(int p , int c)
{
    if(c==4)  //枚举得到了4个硬币
    {
        solve();
        return ;
    }
    for(int i=p+1; i<=n-4+c;i++)
    {
        num[c]=h[i];
        dfs(i,c+1);
    }
    return ;
}
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        if(!n && !m) break;
        for(int i=0; i<n; i++)
            scanf("%d",&h[i]);

        for(int c=0; c<m; c++)
        {
            scanf("%d",&t);
            L=-INF;  R=INF;
            for(int i=0; i<=n-4; i++)
            {
                num[0]=h[i];
                dfs(i,1);
            }
            printf("%d %d\n",L,R);
        }

    }
    return 0;
}

 

posted @ 2013-01-27 22:12  Titanium  阅读(354)  评论(0编辑  收藏  举报