主要大意:给几个立体的矩形块,判断在某一方向能看到哪几个矩形块
注意点: 1.离散化思想,由于是实数点,不可能把所有的点都遍历一遍
所以我们只能将所有的x坐标和x+width坐标排序并去重,相邻两个坐标之间看作一个遍历的位置。
这个区间要么完全可见,要么完全不可见。
如果对任意一个矩形块,这个位置可见,并且前方没有能完全遮住它的矩形块(y < it && heigh >= it),那么这个矩形块就是可见的。
离散化:无限变为有限。这题里即将无限的点变为有限的区间。
2.unique:在STL中unique函数是一个去重函数
unique的功能是去除相邻的重复元素(只保留一个)
其实它并不真正把重复的元素删除,是把重复的元素移到后面去了,然后依然保存到了原数组中,
然后 返回去重后最后一个元素的地址。
继续刷紫书,还是用的紫书的方法。
#include <bits/stdc++.h>
using namespace std;
#define maxn 150
struct mess
{
double x,y,wid,dep,hei;
int id;
mess(double a,double b,double c,double d,double e)
{
x = a; y = b; wid = c; dep = d; hei = e;
}
mess(){}
}house[maxn];
double x[maxn*2];
bool cmp(mess a,mess b)
{
if(a.x == b.x)
return a.y < b.y;
else return a.x < b.x;
}
int cover(int id,double mx)
{
if(house[id].x <= mx && (house[id].x+house[id].wid) >= mx)
return 1;
else return 0;
}
int m,xnum;
int ok(int id)
{
int flag = 0;
for(int i = 0; i < xnum-1; i++)
{
double half = (double)(x[i] + x[i+1])/2;
if(!cover(id,half)) continue;
int mark = 0;
for(int j = 0; j < m ; j++)
{
if(cover(j,half) && house[j].y < house[id].y && house[j].hei >= house[id].hei)
{
mark = 1;
continue;
}
}
if(mark == 0) return 1;
}
return 0;
}
int main()
{
int num = 1;
while(scanf("%d",&m) && m)
{
for(int i = 0; i < m ; i++)
{
double a,b,c,d,e;
scanf("%lf%lf%lf%lf%lf",&a,&b,&c,&d,&e);
house[i] = mess(a,b,c,d,e);
house[i].id = i+1;
x[2*i] = a;
x[2*i+1] = a+c;
}
sort(house,house+m,cmp);
sort(x,x+2*m);
xnum = unique(x,x+2*m) - x;
if(num != 1)
printf("\n");
printf("For map #%d, the visible buildings are numbered as follows:\n",num++);
int inum = 0;
for(int i = 0; i < m; i++)
{
//cout<<"i id "<<i<<' '<<house[i].id<<endl;
if(ok(i) && inum != 0)
printf(" %d",house[i].id);
else if(ok(i) && inum == 0)
{
inum++;
printf("%d",house[i].id);
}
}
printf("\n");
}
return 0;
}