-1 1 3 5 -3 3 4 3 2 1 -3 5 1 2 2 1 1 0 0
6 6 8
題意:給定一些分頻器的高度,從[-1,1]開始注水,問什麼時候漫出去。
思路:惡心的細節題,貪心,找左邊最大的和右邊最高的分隔板,如果相等,時間為中間一塊時間加上兩邊時間少的一塊。如果一邊比較大,那麼最終肯定流到小的那邊,時間計算小的那邊,但是注意還要加上可能流到另一邊的水量,因為如果有分隔板兩邊相等,那麼水流量等於是減半,也可以轉化為,要多流一些水到另一邊,這樣加上這部分的時間即可。
代碼:
#include#include #define min(a,b) ((a)<(b))?(a):(b) const int N = 2005; int l, r, f[N], lv, rv, lmax, rmax, O; void init() { O = -l; for (int i = l; i <= r; i += 2) scanf("%d", &f[i + O]); lv = -1, rv = 1, lmax = f[lv + O], rmax = f[rv + O]; } int solve() { int ans = 0, i, lt = 0, rt = 0; for (i = -1; i >= l; i -= 2) { if (f[i + O] > lmax) { lmax = f[i + O]; lv = i; } } for (i = 1; i <= r; i += 2) { if (f[i + O] > rmax) { rmax = f[i + O]; rv = i; } } int ll = l; for (i = l; i <= lv; i += 2) { if (f[i + O] >= f[ll + O]) { lt += (i - ll) * f[ll + O]; ll = i; } } int rr = r; for (i = r; i >= rv; i -= 2) { if (f[i + O] >= f[rr + O]) { rt += (rr - i) * f[rr + O]; rr = i; } } if (lmax == rmax) ans = (rv - lv) * lmax + (min(lt, rt)) * 2; else { if (lmax > rmax) { for (i = -1; i >= l; i -= 2) if (f[i + O] >= rmax) { lmax = f[i + O]; lv = i; break; } if (lmax == rmax) { int lvv = lv; for (i = lv; i >= l; i -= 2) { if (f[i + O] > rmax) { lmax = f[i + O]; lvv = i; break; } } ans = (rv - lv) * rmax + (min((lv - lvv) * rmax, rt)) + rt; } else ans = rmax * (rv - lv) + rt; } else { for (i = 1; i <= r; i += 2) if (f[i + O] >= lmax) { rmax = f[i + O]; rv = i; break; } if (lmax == rmax) { int rvv = rv; for (i = rv; i <= r; i += 2) { if (f[i + O] > lmax) { rmax = f[i + O]; rvv = i; break; } } ans = (rv - lv) * lmax + (min((rvv - rv) * lmax, lt)) + lt; } else ans = lmax * (rv - lv) + lt; } } return ans; } int main() { while (~scanf("%d%d", &l, &r) && l || r) { init(); printf("%d\n", solve()); } return 0; }