例题5-12 221 Urban Elevations城市正视图

很巧妙的一道题,看了很长时间,也请教了同学。总之就是离散化的应用:

整体思路:

输入房子时,把左上角的X坐标和右上角X坐标输入到一个新的double数组中,作为一个拥有各个房子共同属性的X坐标,对他进行排序,去重(unique),这样只需要看每一个房子是否在这个区间是否可见就可以了,判断是否可见可以在这个区间里任意找一个点(原题是找中点),判断点是不是在房子里!

代码如下:

#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn = 100 + 5;
int T,cont=0;
struct house
{
    int id;
    double x,y,wid,dep,hei;
}rhs[maxn];
bool cmp(const house &a,const house &b){
    return (a.x<b.x)||(a.x==b.x && a.y<b.y);
}
bool cover(int id,double mx){
    return (rhs[id].x <= mx) && (rhs[id].x+rhs[id].wid>=mx);
}
bool visible(int id,double mx){
    if (!cover(id,mx))return false;
    for (int i = 0; i < T; ++i)if (rhs[i].y < rhs[id].y && rhs[i].hei >= rhs[id].hei && cover(i,mx))return false;
    return true;
}
int main()
{
    double x[2*maxn];
    while(scanf("%d",&T) == 1 && T){
        for (int i = 0; i < T; ++i){
            rhs[i].id=i+1;
            scanf("%lf%lf%lf%lf%lf",&rhs[i].x,&rhs[i].y,&rhs[i].wid,&rhs[i].dep,&rhs[i].hei);
            x[i*2]=rhs[i].x;x[i*2+1]=rhs[i].x+rhs[i].wid;//total 2T;
        }
        sort(rhs,rhs+T,cmp);
        sort(x,x+2*T);
        int m = unique(x,x+2*T)-x;
        if (cont++)printf("\n");
        printf("For map #%d, the visible buildings are numbered as follows:\n%d",cont,rhs[0].id);
        for (int i = 1; i < T ; ++i){
            for (int k = 0; k < m-1; ++k){
                if (visible(i,(x[k]+x[k+1]) / 2.0)){printf(" %d",rhs[i].id);break;}
            }
        }
        printf("\n");
    }
    return 0;
}


你可能感兴趣的:(C语言,uva)