最小木块数按列计算,每次取一列(Z轴);最大木块数按层计算,每层尽可能铺满。
(HDU的编译器对于在 C++ 中使用 __int64 和 long long 类型很容易编译错误,且很难排查,建议使用这两种类型时,按照 C 语言的语法,使用 scanf 和 printf)
#include <stdio.h>
#include <string.h>
long long front[100005], side[100005]; //正面和侧面每层的木块数
int frontHigh[100005], sideHigh[100005]; //正面和侧面每个高度出现的次数
int main()
{
int W, L;
while (~scanf("%d %d", &W, &L))
{
memset(front, 0, sizeof(front));
memset(side, 0, sizeof(side));
memset(frontHigh, 0, sizeof(frontHigh));
memset(sideHigh, 0, sizeof(sideHigh));
int frontMaxH = 0, sideMaxH = 0; //正面和侧面最大高度
int temp;
for (int i = 0; i < W; i++) //输入正面
{
scanf("%d", &temp);
frontHigh[temp]++;
for (int j = 1; j <= temp; j++)
{
front[j]++;
}
frontMaxH = temp > frontMaxH ? temp : frontMaxH;
}
for (int i = 0; i < L; i++) //输入侧面
{
scanf("%d", &temp);
sideHigh[temp]++;
for (int j = 1; j <= temp; j++)
{
side[j]++;
}
sideMaxH = temp > sideMaxH ? temp : sideMaxH;
}
if (sideMaxH != frontMaxH)
{
printf("No solution.\n");
continue;
}
long long M = 0, N = 0; //最少木块数,最多木块数
for (int i = 1; i <= frontMaxH; i++) //计算最少木块数
{
if (frontHigh[i] > 0 || sideHigh[i] > 0)
{ //按各高度的最大数量取木块,按列取
if (frontHigh[i] > sideHigh[i])
M += frontHigh[i] * i;
else
M += sideHigh[i] * i;
}
}
for (int i = 1; i <= frontMaxH; i++) //计算最多木块数
{ //每层填满,为矩形,按层取
N += front[i] * side[i];
}
printf("%lld %lld\n", M, N);
}
return 0;
}
继续加油。