问题描述:
一天,小希用积木搭了个城堡,并且照了正面和侧面的照片(前视图和右视图)给Gardon看,让Gardon猜猜她究竟用了多少块积木;Gardon发现从这两张照片上只能看出每一列上最高的地方有多高,但是无法推测出具体的形状(见图1、2),但是好在小希给了Gardon多次机会,所以Gardon只需要知道大概的范围就可以采用“二分查找”法来计算正确的结果。现在Gardon请你帮忙,根据这两张图,计算下最少和最多分别可能是多少块积木组成的,让他可以尽快的回答出小希的问题。
样例输入:
输入可能包含多组数据。每组数据的第一行分别有两个数:W和L(0
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
int main()
{
int w, l;
while(~scanf("%d %d", &w, &l))
{
long long m = 0, n = 0;
int maxp = 0, maxs = 0;
long long positive[100005], side[100005]; //正面和侧面看去每层有多少木块
int positive_high[100005], side_high[100005]; //正面和侧面每个高度出现的次数
memset(positive, 0, sizeof(positive));
memset(side, 0, sizeof(side));
memset(positive_high, 0, sizeof(positive_high));
memset(side_high, 0, sizeof(side_high));
int temp;
for(int i = 0; i < w; i++)
{
scanf("%d", &temp);
positive_high[temp]++;
for(int j = 1; j <= temp; j++)
{
positive[j]++;
}
maxp = temp > maxp ? temp : maxp;
}
for(int i = 0; i < l; i++)
{
scanf("%d", &temp);
side_high[temp]++;
for(int j = 1; j <= temp; j++)
{
side[j]++;
}
maxs = temp > maxs ? temp : maxs;
}
if(maxs != maxp)
{
printf("No solution.\n");
continue;
}
for(int i = 1; i <= maxp; i++)
{
n += positive[i] * side[i]; //最大值,每层正面和侧面的乘积
}
for(int i = 1; i <= maxp; i++)
{
if(positive_high[i] || side_high[i])
{
m += max(positive_high[i], side_high[i]) * i; //最小值,对于每个出现的高度正面和侧面中取最大值
}
}
printf("%lld %lld\n", m, n);
}
return 0;
}