题目大意:给出l和r,然后从l坐标到r坐标每隔两个位置有一个档板,给出挡板的高度,然后想(-1, 1)中间加水,问什么时候会溢出。
解题思路:两边先找到距离(-1,1)最近的最大值L和R,因为可能存在多个最高的挡板。
接着比较两个L和R的大小,相等的话就可以比较(-l,L的下标)和(R的下标,r)两块的大小,注意L和R一边高的话两边都会流,所以这块的时间要乘2。
如果两边不一般高的话,找到高的一边第一个比另一边最高的那个高的p(细节比较多,自己多想一下就知道了),然后比较a = ( p,Max(R,L)的下标)和b = (Min(R,L)的下标,end)的大小,然后决定是2*b还是a+b。
#include#include #include using namespace std; const int N = 1005; int l, r, x[N], y[N]; int L, R, idl, idr; void init() { R = L = 0; for (int i = l; i <= r; i += 2) { if (i < 0) { scanf("%d", &x[(-i)/2]); if (L <= x[(-i)/2]) { L = x[(-i)/2]; idl = (-i)/2; } } else { scanf("%d", &y[i/2]); if (R < y[i/2]) { R = y[i/2]; idr = i/2; } } } } int del(int a, int b) { if (a <= b) return 2 * a; else return a + b; } int solve() { l = (-l) / 2; r = r / 2; if (R == L) { int k = 0, t = 0; int tmp = x[l]; for (int i = l; i > idl; i--) { k += tmp; tmp = max(tmp, x[i-1]); } tmp = y[r]; for (int i = r; i > idr; i--) { t += tmp; tmp = max(tmp, y[i-1]); } return (idl + idr + 1) * R * 2 + min(k, t) * 2 * 2; } else { int T = min(R, L); int p = 0, q = 0, k = 0, t = 0; while (p < l && x[p] < T) p++; while (q < r && y[q] < T) q++; if (R > L) { int tmp = y[q]; for (int i = q; y[i] <= L; i++) { k += tmp; tmp = max(tmp, y[i+1]); } tmp = x[l]; for (int i = l; i > p; i--) { t += tmp; tmp = max(tmp, x[i-1]); } } else { int tmp = x[p]; for (int i = p; x[i] <= R; i++) { k += tmp; tmp = max(tmp, x[i+1]); } tmp = y[r]; for (int i = r; i > q; i--) { t += tmp; tmp = max(tmp, y[i-1]); } } int ans = t > k ? t + k : 2 * t; return ans * 2 + (p + q + 1) * T * 2; } } int main() { while (scanf("%d%d", &l, &r) == 2 && l && r) { init(); printf("%d\n", solve()); } return 0; }