思路:
若某点水位为h,那么从此h向左右延伸都小于等于ceil,不触碰ceil。
一次扫描维护两边复杂度为O(n^2),显然不可行。
所以扫描两次,第一次扫描使得每点h为左延伸不碰壁的最大高度。
注意当此时水位h < floor时,可以提高到floor,显然仍满足延伸不碰壁条件。
h1与h2皆为满足单条件的最大值,min(h1, h2)即为所求点水位高度最大值。
若某点水位为h,那么从此h向左右延伸都小于等于ceil,不触碰ceil。
一次扫描维护两边复杂度为O(n^2),显然不可行。
所以扫描两次,第一次扫描使得每点h为左延伸不碰壁的最大高度。
注意当此时水位h < floor时,可以提高到floor,显然仍满足延伸不碰壁条件。
h1与h2皆为满足单条件的最大值,min(h1, h2)即为所求点水位高度最大值。
#include <set>
#include <map>
#include <ctime>
#include <cmath>
#include <stack>
#include <queue>
#include <deque>
#include <cstdio>
#include <string>
#include <vector>
#include <cctype>
#include <sstream>
#include <utility>
#include <cstring>
#include <cstdlib>
#include <functional>
#include <iostream>
#include <algorithm>
#define SF(a) scanf("%d", &a)
#define PF(a) printf("%d\n", a)
#define SFF(a, b) scanf("%d%d", &a, &b)
#define SFFF(a, b, c) scanf("%d%d%d", &a, &b, &c)
#define SFFFF(a, b, c, d) scanf("%d%d%d%d", &a, &b, &c, &d)
#define CLEAR(a, b) memset(a, b, sizeof(a))
#define IN() freopen("in.txt", "r", stdin)
#define OUT() freopen("out.txt", "w", stdout)
#define FOR(i, a, b) for(int i = a; i < b; ++i)
#define LL long long
#define maxn 10000005
#define maxm 205
#define mod 1000000007
#define inf 1000000007
#define eps 1e-4
using namespace std;
int buf[20], l;
int read() {
int x = 0; char ch = getchar(); bool f = 0;
while (ch < '0' || ch > '9') { if (ch == '-') f = 1; ch = getchar(); }
while (ch >= '0' && ch <= '9') x = (x << 1) + (x << 3) + (ch ^ 48), ch = getchar();
return f ? -x : x;
}
void write(int x) {
if (!x) { putchar(48); return; }
l = 0; if (x < 0) putchar('-'), x = -x;
while (x) buf[++l] = x % 10, x = x / 10;
while (l) putchar(buf[l--] + 48);
}
//-------------------------chc------------------------------//
int f[maxn], c[maxn];
int h1[maxn], h2[maxn];
int main() {
int t = read();
while (t--) {
int n = read();
FOR(i, 0, n) f[i] = read();
FOR(i, 0, n) c[i] = read();
int h = c[0];
h1[0] = h;
FOR(i, 1, n) {
if (h > c[i]) h = c[i];
if (h < f[i]) h = f[i];
h1[i] = h;
}
h2[n-1] = h = c[n - 1];
for (int i = n - 2; i >= 0; --i) {
if (h > c[i]) h = c[i];
if (h < f[i]) h = f[i];
h2[i] = h;
}
int ans = 0;
FOR(i, 0, n) ans = min(h1[i], h2[i]) - f[i];
}
return 0;
}
本文介绍了ACM/ICPC算法竞赛中的一道题目——洞穴(UVa1442),并提供了高效的解决方案。通过两次扫描找到每个位置水位的最大高度,避免了O(n^2)的复杂度,实现了O(n)的时间复杂度。代码中使用了C++的数据结构和算法,包括二维数组、循环遍历以及动态更新最大高度等技巧。
&spm=1001.2101.3001.5002&articleId=78748809&d=1&t=3&u=ececc38584be4119945d0ecdfaca0fb2)
1000

被折叠的 条评论
为什么被折叠?



