题意:
给定不同厚度的硬币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;
}