UVA 221 Urban Elevations 离散化 模拟

来源:互联网 发布:淘宝衣服拍照技巧图片 编辑:程序博客网 时间:2024/06/11 03:19

题意:给出一张俯视图。给出N个建筑物的左下标,长度,宽度,高度。现在求,从南面看,能看到那些建筑?

思路:沿Y轴的宽度是没用的,直接忽略。

          然后,对左边先按x排序,在按y排序。我们分别判别那些建筑是可见的。

          对于可见,我们需要扫描整个区间,但因为这个是实数的区间,我们需要离散化。我们将每个建筑的左边边界和右边边界分别当成一个事件点。对所有的事件点进行排序。那么任意两个相近的事件点就是基本事件区间。对于这个基本事件区间,我们有以下性质:在这个基本的区间里,一个建筑要么完全可见,要么完全不可见。

         这样,我们对于每个建筑,扫描所有的基本事件区间,判断他在那个区间里可见,即该建筑在对应区间内,且在区间内位置比他靠前的建筑的高度斗殴比他小。

代码如下:

#include <cstdio>#include <algorithm>#include <cstring>using namespace std;const int MAX = 110;int n;double x[MAX<<1];struct Building{    int id;    double x,y,w,d,h;    bool operator < (const Building& rhs) const{        return x < rhs.x || (x == rhs.x && y < rhs.y);    }} b[MAX];bool cover(int i, double mx){    return b[i].x <= mx && b[i].x + b[i].w >= mx;}bool visible(int i, double mx){    if(!cover(i,mx)) return false;    for(int k = 0; k < n; ++k)        if(b[k].y < b[i].y && b[k].h >= b[i].h && cover(k,mx)) return false;    return true;}int main(void){    //freopen("input.txt","r",stdin);    int cas = 0;    while(scanf("%d", &n),n){        for(int i = 0; i < n; ++i){            scanf("%lf%lf%lf%lf%lf",&b[i].x,&b[i].y,&b[i].w,&b[i].d,&b[i].h);            x[i<<1] = b[i].x, x[(i<<1)|1] = b[i].x+b[i].w;            b[i].id = i + 1;        }        sort(b, b+n);        sort(x,x + 2 * n);        int m = unique(x,x + 2 * n) - x;        if(cas++) puts("");        printf("For map #%d, the visible buildings are numbered as follows:\n%d",cas,b[0].id);        for(int i = 1; i < n; ++i){            bool vis = false;            for(int j = 0; j < m-1;++j)            if(visible(i,(x[j] + x[j+1]) / 2.0)){                vis = true;                break;            }            if(vis) printf(" %d",b[i].id);        }        puts("");    }    return 0;}

0 0
原创粉丝点击