溢水鱼缸
为了能够更快加水,在鱼缸上面放m个水龙头,每个水龙头的位置都在某两个相邻的隔板中间,且高度高于两边侧面。已知没有两个水龙头的位置相同。初始时鱼缸是空的,m个水龙头同时开始流水,每个水龙头的流速都是每秒1(单位3)。我们想知道,经过多长时间后水才会从最左边或最右边的隔板处溢出鱼缸。
输入格式:从键盘输入若干组数据。每组数据有3行。第一行为两个正整数n,m (0 < n, m ≤ 1000000, m ≤ n),分别表示鱼缸的长度和水龙头的个数。第二行为n+1个互不相同的正整数,顺序表示从左到右每个隔板的高度。所有的高度都不超过10000000。第三行为m个互不相同的正整数X1, X2, …, Xm,分别表示m个水龙头的位置。第i个数Xi表示第i个水龙头是在第Xi个隔板与第Xi+1个隔板之间。水龙头是按从左至右给出的,也就是输入数据保证0<=X1<X2<…<Xm。输入为0 0表示结束。
输出格式:输出到屏幕。对于每一组数据,输出结果占一行。输出一个实数,表示水开始溢出鱼缸的时间。在计算时,忽略隔板的厚度,结果保留3位小数。
【样例输入】
4 2
2 3 5 1 4
1 2
10 1
5 80 57 82 36 98 62 50 12 96 83
6
0 0
【样例输出】
5.000
467.000
#include <iostream>
#include <limits>
#include <iomanip>
using namespace std;
int main()
{
int n, m; // 鱼缸长度和水龙头个数
for (;;)
{
cin >> n >> m;
if (n == 0 && m == 0) // 数据结束
break;
int *H = new int[n+1]; // 隔板高度
int *X = new int[m]; // 水龙头位置
for (int i = 0; i <= n; i++)
cin >> H[i];
for (int i = 0; i < m; i++)
cin >> X[i];
int maxHP = 0; // 最高隔板的位置
for (int i = 1; i <= n; i++)
if (H[i] > H[maxHP])
maxHP = i;
double minTime = numeric_limits<double>::max(); // 最短溢水时间
double V = 0; // 之前所有阶梯状区域的蓄水量
int leftP = 0; // 前一层阶梯区域的右侧隔板位置,即新一层阶梯区域的左侧隔板位置
int nextX = 0; // 下一个要考虑位置的水龙头编号
while (leftP < maxHP) // 不超过最高隔板
{
// 查找新一层阶梯区域的右侧位置
int rightP = leftP + 1; // 新一层阶梯区域的右侧隔板位置
while (H[rightP] < H[leftP]) rightP++; // 找到比左侧高的隔板作为右侧
for (; nextX < m && X[nextX] < rightP; nextX++); // 确定区域内的水龙头
V += H[leftP] * (double)(rightP - leftP); // 新增蓄水量
if (nextX != 0 && V / nextX < minTime) // 更新最短溢水时间
minTime = V / nextX;
leftP = rightP; // 递推条件
}
V = 0;
int rightP = n; // 前一层阶梯区域的左侧隔板位置,即新一层阶梯区域的右侧隔板位置
nextX = m - 1; // 下一个要考虑位置的水龙头编号
while (rightP > maxHP) // 不超过最高隔板
{
int leftP = rightP - 1; // 新一层阶梯区域的左侧隔板位置
while (H[leftP] < H[rightP]) leftP--; // 找到比右侧高的隔板作为左侧
for (; nextX >= 0 && X[nextX] > leftP; nextX--); // 确定区域内的水龙头
V += H[rightP] * (double)(rightP - leftP); // 新增蓄水量
if (nextX != m-1 && V / (m - 1 - nextX) < minTime) // 更新最短溢水时间
minTime = V / (m - 1 - nextX);
rightP = leftP; // 递推条件
}
cout << fixed << setprecision(3) << minTime << endl;
delete []H;
delete []X;
}
return 0;
}