题目大意:给出建筑的俯视图,以及每个建筑的左下角坐标,宽度,长度,高度。求正视图可观察到的建筑的编号
思路:建筑物的可见性等于南墙的可见性,依据左下角排序后,逐个判断每个建筑是否可见。对南墙的x坐标进行排序,相邻两个x坐标之间的南墙可见性一致,通过判断这部分南墙中的特殊点(中间点)可以得到这部分墙的可见性。如果这部分墙可见,那么这部分墙
归属的建筑可见。
#include<bits/stdc++.h> using namespace std; #define LL long long #define INF 999999999 bool vis[120]; int x[240]; struct node { double x,y,w,d,h,id; } p[120]; bool cmp(struct node A,struct node B) { if(A.x != B.x) return A.x < B.x; return A.y < B.y; } bool check(int posx,int k,int n) { double mid = (x[posx] + x[posx+1]) / 2.0; if(mid<p[k].x || mid>p[k].x+p[k].w) return false; for(int i=0;i<n;i++) { if(p[i].y<p[k].y && p[i].h>=p[k].h && p[i].x<=mid && mid<=p[i].x+p[i].w) return false; } return true; } int main() { int n,cnt =1; while(cin >> n && n) { if(cnt > 1) cout << endl; int pos = 0; for(int i=0; i<n; i++) { cin >> p[i].x >> p[i].y >> p[i].w >> p[i].d >> p[i].h; p[i].id = i+1; x[pos++] = p[i].x; x[pos++] = p[i].x + p[i].w; } sort(p,p+n,cmp); sort(x,x+pos); int numx = unique(x,x+pos) - x; cout << "For map #" << cnt++ << ", the visible buildings are numbered as follows:" << endl; cout << p[0].id; for(int i=1;i<n;i++) { for(int j=0;j<numx;j++) { if(check(j,i,n)) { cout << " " << p[i].id; break; } } } cout << endl; } return 0; }