UVa #10366 Faucet Flow (习题8-24)

来源:互联网 发布:深圳技校分数线知乎 编辑:程序博客网 时间:2024/05/12 04:48

一直想做一道扫描法的题,终于。。here it is。。


不明白为什么这道题在uva数据那么惨。不是很难的吧。。16xx那么难可数据那么好看一定是因为根本就没人做!全是测试号的数据!最近被16xx的题恶心坏啦


这个题就是从前往后扫描,扫的时候记录下到目前为止的最高木板和位置就好了。在跨越中点后,分几种情况讨论下就好了。主要是注意好跨中点的高度相等的木板。


比起UVa#1610 Party Game (习题8-2),分类讨论的规模不算很恶心。


Run Time: 0.016s

#define UVa  "8-24.10366.cpp"//Faucet Flow#include<cstring>#include<cstdio>#include<vector>using namespace std;struct Divider {    int h, x;    Divider(int a, int b):h(a),x(b){}};//Global Variables.const int maxn = 1000 + 10;int leftx, rightx;vector<Divider> v;int main() {    while(scanf("%d%d", &leftx, &rightx) && leftx) {        int a, i;        v.clear();        for(int i = leftx; i <= rightx; i += 2) {            scanf("%d", &a);            v.push_back(Divider(a, i));        }        int rcdh = v[0].h, rcdx = v[0].x;        long long ans1 = 0, ans2 = 0;        for(i = 1; i < v.size(); i ++) {        //left->right            Divider& d = v[i];            if(d.h > rcdh) {                ans1 += rcdh * (d.x - rcdx);                if(d.x * rcdx < 0) break;                rcdh = d.h;                rcdx = d.x;            }            else if(d.h == rcdh) {                if(d.x*rcdx < 0) {  //opposite side. same side: ignore.                    int j = i + 1;                    while(j < v.size() && v[j].h <= d.h) j ++;                    if(j == v.size()) {     //no higher dividers through other end.                        long long tmp = v[v.size() - 1].x - d.x;                        tmp *= d.h;                        ans1 += min(tmp, ans1);                        ans1 += d.h * (d.x - rcdx);                    }                    else {                        long long tmp = v[j].x - d.x;                        tmp *= d.h;                        ans1 += min(tmp, ans1);                        ans1 += d.h * (d.x - rcdx);                    }                    break;                }                else {                    ans1 += (d.x - rcdx) * d.h;                    rcdx = d.x;                }            }        }        if(i == v.size() && rcdx < 0) ans1 = 10000000000000L;        i = v.size() - 1;        rcdh = v[i].h, rcdx = v[i].x;        for(i = v.size() - 1; i >= 0; i --) {           //right->left            Divider& d = v[i];            if(d.h > rcdh) {                ans2 += rcdh * (rcdx - d.x);                if(d.x * rcdx < 0) break;                rcdh = d.h;                rcdx = d.x;            }            else if(d.h == rcdh) {                if(d.x*rcdx < 0) {  //opposite side. same side: ignore.                    int j = i - 1;                    while(j >= 0 && v[j].h <= d.h) j --;                    if(j == -1) {     //no higher dividers through other end.                        long long tmp = d.x - v[0].x;                        tmp *= d.h;                        ans2 = ans2 + min(tmp, ans2);       //min: if leaking to other side is better, do it.                        ans2 += d.h * (rcdx - d.x);                    }                    else {                        long long tmp = d.x - v[j].x;                        tmp *= d.h;                        ans2 = ans2 + min(tmp, ans2);                        ans2 += d.h * (rcdx - d.x);                    }                    break;                }                else {                    ans2 += (rcdx - d.x) * d.h;                    rcdx = d.x;                }            }        }        if(i == -1 && rcdx > 0) ans2 = 10000000000000L;        printf("%lld\n", min(ans1, ans2));    }    return 0;}


0 0
原创粉丝点击