A faucet is pouring water into a long, thin aquar-ium with various vertical dividers (walls) in it. Theaquarium is initially empty, and its bottom is per-fectly level. How long will it take for water to spillover its left- or right-most divider? The faucet isabove location x = 0, and the dividers are located atx = −1,−3,−5,...leftx and 1,3,5,...rightx. The di-viders are attached perpendicular to the floor and sidesof the aquarium, and have various heights. The aquar-ium’s length is greater than rightx −leftx, its walls arehigher than the highest divider, and its width is 1 uniteverywhere. Water pours from the faucet at a rate of1 cubic unit per second.
You may assume that water is an ideal liquid: italways flows downhill and if it cannot flow downhill itspreads at an equal rate in all horizontal directions.
解题:这一题主要时注意到两边的最大值。明显又一边最大值比较大时,那么肯定是另一边先到达边界,因为这一边肯定 不会到达边界。
所以这一题就是注意最大值之间的关系。
具体情况可看代码。易懂,另外附上一些测试数据
-1 3
5 5 5
-3 5
5 5 5 5 5
-7 9
1 2 3 4 1 1 1 4 5
-7 15
1 2 3 4 1 1 1 4 4 4 4 4
-9 7
5 4 1 1 1 4 3 2 1
-15 7
4 4 4 4 4 1 1 1 4 3 2 1
-7 7
4 3 2 1 1 2 3 4
-7 7
4 3 2 1 1 2 2 4
-7 7
4 3 1 1 1 2 3 4
-7 9
4 3 2 1 1 2 3 4 1
-9 7
1 4 3 2 1 1 2 3 4
-7 9
2 1 1 5 5 1 1 1 2
-1 1
1 1
-1 1
2 1
-7 5
1 1 1 2 3 4 3
-11 9
1 3 5 7 9 10 10 8 6 4 2
-9 9
1 4 3 2 1 1 2 3 4 1
-9 11
1 4 3 2 1 1 2 3 4 1 2
-11 9
2 1 4 3 2 1 1 2 3 4 1
-3 15
19 20 20 1 1 1 1 1 1 1
-3 15
19 20 20 3 3 3 3 3 3 3
-15 3
1 1 1 1 1 1 1 20 20 19
-15 3
3 3 3 3 3 3 3 20 20 19
-15 3
8 3 8 3 3 7 2 1 7 2
-9 9
5 5 8 7 4 2 8 6 10 7
-9 9
7 10 6 8 2 4 7 8 5 5
-3 7
10 4 4 4 2 1
-11 7
10 2 2 2 2 4 4 4 2 1
答案:
10
30
52
56
52
56
56
56
56
56
56
34
2
2
10
100
60
60
60
68
116
68
116
50
104
104
30
36
//
// main.cpp
// uva 10366 - Faucet Flow
//
// Created by XD on 15/8/19.
// Copyright (c) 2015年 XD. All rights reserved.
//
#include <iostream>
#include <string>
#include <queue>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include<vector>
#include <string.h>
#include <string>
#include <algorithm>
#include <set>
#include <map>
#include <cstdio>
#define ll long long
using namespace std ;
const int maxn =1000 + 10 ;
struct divider{
int high ;
int pos ;
};
int wall_left[maxn] ;
int wall_right[maxn] ;
int l ,r ,n;
ll min(ll x , ll y)
{
return x < y ? x :y ;
}
int main(int argc, const char * argv[]) {
ll ans = 0 ;
while (scanf("%d%d" ,&l,&r)==2&&r!=0&&l!=0) {
ans = 0 ;
//输入左边的墙的高度
int len1=( -l + 1)/2 ;
int max1 = 0 ;int pos1= 0 ;
ll ans1 = 0 ;ll temp_max = 0 ;
for (int i = 0; i < len1; i++) {
scanf("%d" ,&wall_left[i]) ;
if (max1 <=wall_left[i]) {
max1 = wall_left[i] ;
pos1 = i ;
}
}
//统计越左边的最高的墙的左边边界需要的水的体积的二倍
temp_max = wall_left[0] ;
for (int i = 1; i <=pos1; i++) {
if (wall_left[i] <= temp_max) {
ans1+=(temp_max * 4) ;
}
else{
ans1+=(temp_max*4) ;
temp_max = wall_left[i] ;
}
}
//输入左边的墙的高度
int len2 = (r +1)/2 ;
int max2 = 0 ;int pos2 = 0 ;ll ans2 = 0 ;
for (int i = 0 ; i < len2; i++) {
scanf("%d" ,&wall_right[i]) ;
if (max2 <wall_right[i]) {
max2 = wall_right[i] ;
pos2 = i ;
}
}
//统计右边的最高的墙的右边边界需要的水的体积的二倍
temp_max = wall_right[len2-1] ;
for (int i = len2-2; i >=pos2; i--) {
if (wall_right[i] <= temp_max) {
ans2+=(temp_max * 4) ;
}
else{
ans2+=(temp_max*4) ;
temp_max = wall_right[i] ;
}
}
//左右两边的最高墙之间的关系。
/*
这里主要注意一种情况就是 当有一边的最大值比较大(假设为右边)时,要注意右边的第一个等于max1的和第一个大于max1的。
*/
if (max1> max2) {
int tpos1 = -1 ;int tpos2 = -1 ;
for (int i = len1-1; i>=pos1 ; i--) {
if (wall_left[i]==max2) {
if (tpos1==-1) {
tpos1 = i ;
}
}
if (wall_left[i] > max2) {
tpos2 = i ;
break ;
}
}
if (tpos1 == -1) {
ans = max2 *(len1 - tpos2 + pos2) *2 + ans2/2 ;
}
else{
ll ans3 = max2 * (tpos1 - tpos2) *2 ;
if (ans3 > ans2/ 2) {
ans = max2 * (len1 - tpos1 + pos2)*2 + ans2 ;
}
else{
ans = max2 * (len1 - tpos1 + pos2)*2 + ans3 * 2 +(ans2/2 - ans3) ;
}
}
}
else if ( max1 == max2)
{
ans =max2 * (pos2 + len1 - pos1 ) *2 ;
ans =ans + min(ans1 , ans2) ;
}
else{
int tpos1 = -1 ;int tpos2 = -1 ;
for (int i = 0; i<=pos2 ; i++) {
if (wall_right[i]==max1) {
if(tpos1==-1 )tpos1 = i ;
continue ;
}
if (wall_right[i] > max1) {
tpos2 = i ;
break ;
}
}
if (tpos1 == -1) {
ans = max1 *(tpos2 + len1 - pos1 ) *2 + ans1/2 ;
}
else{
ll ans3 = max1 * (tpos2 - tpos1) *2 ;
if (ans3 > ans1/ 2) {
ans = max1 * (len1 - pos1 + tpos1)*2 + ans1 ;
}
else{
ans = max1 * (len1 - pos1 + tpos1)*2 + ans3 * 2 +(ans1/2 - ans3) ;
}
}
}
printf("%lld\n",ans) ;
}
return 0;
}