• UVa 221


    题意

    城市俯视图 给出坐标,长宽高, 求从南向北(朝着y周正方向)看, 正视图能看到的楼号

    思路

    因为坐标可能会有double类型的, 所以没法枚举每一个横坐标
    这里引用一下紫书的思路
    记得控制一下格式

    把所有x坐标排序去重,则任意两个相邻x坐标形成的区间具有相同属性,一个区间要么完全可见,要么完全不可见。这样,只需在这个区间里任选一个点(例如中点),就能判断出一个建筑物是否在整个区间内可见。如何判断一个建筑物是否在某个x坐标处可见呢?首先,建筑物的坐标中必须包含这个x坐标,其次,建筑物南边不能有另外一个建筑物也包含这个x坐标,并且不比它矮。

    AC代码

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <set>
    
    using namespace std;
    const int maxn = 300;
    set<int> setid;
    set<double> setdx;
    double dx[maxn];
    
    struct building{
        int id;
        double x,y,w,d,h,xx;
    }p[maxn/2];
    
    bool cmp( struct building a, struct building b )
    {
        if( a.x == b.x )
            return a.y < b.y;
        return a.x < b.x;
    }
    int T;
    bool judge( double point, struct building a ){
        if( a.y == 0 )  return true;
        if( a.xx < point || a.x > point )   return false;
        for( int i = 0; i < T; i++ ){
            //cout << "point : " << point << " xx : " << p[i].xx << endl;
            if( point >= p[i].x && point <= p[i].xx ){
                if( p[i].y < a.y && p[i].h >= a.h )
                    return false;
            }
        }
        return true;
    }
    
    int main()
    {
        int i, j, len, num, casenum = 0;
        while( scanf("%d",&T) == 1 && T ){
            for( i = 0; i < T; i++ ){
                p[i].id = i+1;
                scanf("%lf%lf%lf%lf%lf",&p[i].x,&p[i].y,&p[i].w,&p[i].d,&p[i].h);
                p[i].xx = p[i].x + p[i].w;
                if(!setdx.count(p[i].x))  setdx.insert(p[i].x);
                if(!setdx.count(p[i].xx))  setdx.insert(p[i].xx);
            }
            set<double>::iterator it;
            for( it = setdx.begin(), i = 0; it != setdx.end(); it++, i++ )
                dx[i] = *it;
            len = i;
            sort(p, p+T, cmp);
            if( casenum != 0 )  putchar('
    ');
            printf("For map #%d, the visible buildings are numbered as follows:
    ",++casenum);
            num = 0;
            for( i = 0; i < T; i++ ){
                if( setid.count(p[i].id) )  continue;
                for( j = 0; j < len; j++ ){
                    if( p[i].xx < dx[j] )  break;
                    if( dx[j] >= p[i].x || dx[j+1] <= p[i].xx ){
                        if( judge( (dx[j]+dx[j+1])/2.0 ,p[i] ) ){
                            if( ++num != 1 )    printf(" ");
                            printf("%d",p[i].id);
                            setid.insert(p[i].id);
                            break;
                        }
                    }
                }
            }
            putchar('
    ');
            if( !setid.empty() )    setid.clear();
            if( !setdx.empty() )    setdx.clear();
            memset(dx,0,sizeof(dx));
        }
        return 0;
    }
  • 相关阅读:
    简单的远程控制软件
    VS集成环境中的JavaScript脚本语法检查
    vs2022安装
    有关httpContext.Current.Session[值] 取值的问题
    【python3.7】文件操作
    148. 排序链表
    11. 盛最多水的容器
    23. 合并K个升序链表
    147. 对链表进行插入排序
    146. LRU 缓存机制
  • 原文地址:https://www.cnblogs.com/JinxiSui/p/9740619.html
Copyright © 2020-2023  润新知