UVa 10717 Mint(LCM)

题意:

给定不同厚度的硬币n 选出其中的四个,然后组成四个桌腿并且要使每个桌腿高度一样

给定的高度h, 分别求不大于h的最大的高度和不小于h的最小高度

思路:

枚举硬币,然后更新状态即可。

#include <cstdio>
#include <cstring>
#include <cstring>

#define LL long long int 

int coin[60], tab[60];
LL low[20], high[20];
int n, t;

LL gcd(LL x, LL y)
{
    LL t;
    while (y)
    {
        t = x % y;
        x = y;
        y = t;
    }
    return x;
}

LL calclcm(LL a, LL b, LL c, LL d)
{
    LL temp, ans;
    temp = gcd(a, b);
    ans = a * b / temp;
    temp = gcd(ans, c);
    ans = ans * c / temp;
    temp = gcd(ans, d);
    ans = ans * d / temp;
    return ans;
}

void solve()
{
    memset(low, 0, sizeof(low));
    memset(high, 0x3f, sizeof(high));

    for (int i = 0; i < n; ++i)
        for (int j = i + 1; j < n; ++j)
            for (int p = j + 1; p < n; ++p)
                for (int q = p + 1; q < n; ++q)
                {
                    LL ans = calclcm(coin[i], coin[j], coin[p], coin[q]);
                    for (int k = 0; k < t; ++k)
                    {
                        if (ans < tab[k] && tab[k] - tab[k]%ans > low[k])
                            low[k] = tab[k] - tab[k]%ans;
                        if ((ans - tab[k]%ans) % ans + tab[k] < high[k])
                            high[k] = (ans - tab[k]%ans) % ans + tab[k];
                    }
                }
}

int main()
{
    while (scanf("%d %d", &n, &t) && n && t)
    {
        for (int i = 0; i < n; ++i)
            scanf("%d", &coin[i]);
        for (int i = 0; i < t; ++i)
            scanf("%d", &tab[i]);

        solve();

        for (int i = 0; i < t; ++i)
            printf("%lld %lld\n", low[i], high[i]);
    }

    return 0;
}

 

posted @ 2012-12-04 21:56  kedebug  阅读(219)  评论(0编辑  收藏  举报