Water on the Stairs
Problem Description
You are the manager for Stair World amusement park, a 2-dimensional theme park that specializes in death-defying staircase walks (otherwise known as “rides”) for stick figures. Unfortunately, it’s been raining for months, and every staircase ride is full of water to the point of overflowing. Your customers, who are extreme walkers, can’t walk on water and are not interested in swimming. You contract with a company to pump out the water, but they first need to know the area of water present in order to properly price the job. How much water must be pumped out of each ride? The figure to the right shows a staircase ride (line segments) filled with water (shaded regions). Note that water must be bounded by portions of the staircase ride on the left, on the right and below, otherwise it overflows.
Input
The input consists of ?staircase rides ?1, ?2, …, ??that need to be emptied of water. The first line of input contains the number of staircase rides ?<100; the remaining lines specify each staircase ride. Staircase ride s_i begins with an integer ?? <1000, on a single line followed by ?? pairs of non-negative integers (??,??), one per line, where 1≤ ? ≤ ??, and ?? and ?? are each less than 1000. Each pair of consecutive points (??,??) and (?x?+1,?y?+1) forms a horizontal or vertical line segment of positive length such that ?x? ≤ ?x?+1and consecutive line segments alternate between vertical and horizontal line segments. Each staircase ride begins and ends with a horizontal segment.
Output
The output consists of ?integers, one per line, where line i has the area of the water for staircase ride s_i.
Sample Input
2
10
(0,50)
(1,50)
(1,30)
(2,30)
(2,40)
(3,40)
(3,20)
(4,20)
(4,80)
(5,80)
20
(123,17)
(126,17)
(126,27)
(136,27)
(136,25)
(140,25)
(140,24)
(143,24)
(143,125)
(148,125)
(148,118)
(156,118)
(156,120)
(159,120)
(159,107)
(166,107)
(166,113)
(169,113)
(169,103)
(189,103)
Sample Output
60
75
Solution
从最底下边往上枚举,分别检查两边最近的形如‘凹’的变,并累计答案(特别要注意查重,不然可能会累加重复)
AC Code
Author: 队友Ou Jian
#include <bits/stdc++.h>
#define _for(i, j, k) for(int i=j;i<=k;++i)
#define LL long long
using namespace std;
const int maxn = 1e3 + 5;
int t, n, X[maxn], Y[maxn], len;
int findL(int ind, int &L) {
for (int i = ind - 1; i > 0; --i) {
if (X[i] == X[i + 1] && Y[i] > Y[i + 1] && Y[i] > Y[ind]) {
L = X[i];
return Y[i] - Y[ind];
}
}
return 0;
}
int findR(int ind, int &R) {
_for(i, ind + 1, n - 1) {
if (X[i] == X[i + 1] && Y[i] < Y[i + 1] && Y[i + 1] > Y[ind]) {
R = X[i];
return Y[i + 1] - Y[ind];
}
}
return 0;
}
set<pair<int, int> > sp;
int main() {
cin >> t;
string line;
while (t--) {
cin >> n;
_for(i, 1, n) {
cin >> line;
len = line.length();
_for(j, 0, len - 1) if (line[j] == '(' || line[j] == ')' || line[j] == ',') line[j] = ' ';
stringstream ss(line);
ss >> X[i] >> Y[i];
}
LL an = 0;
_for(i, 1, n - 1) {
if (Y[i] == Y[i + 1]) {
int L = X[i], R = X[i + 1];
int HL = findL(i, L), HR = findR(i, R);
if (!sp.count(pair<int, int>{L, R})) {
an += (LL) (R - L) * min(HL, HR);
sp.insert(pair<int, int>{L, R});
}
}
}
cout << an << "\n";
sp.clear();
}
return 0;
}