这是一道区间离散化的题目,看紫书只有代码和一点讲解,楞是没看懂,一看这位大佬的解释就懂了
在代码下添加了注释,希望对你们有帮助。
链接: 大佬讲解.
#include <bits/stdc++.h>
using namespace std;
const int maxn = 105;
struct build
{
int id;
double x,y,w,d,h;
bool operator <(const build &a)const
{
//按照左下角x坐标升序,当左下角一样大时,按y坐标升序
if(a.x=x)
return a.y<y
else
return a.x<x;
}
}b[maxn];
//判断在区间中点mx是否在建筑的x坐标范围内
bool cover(int i,double mx)
{
return b[i].x<=mx && b[i].x+b[i].w >= mx;
}
//判断第i栋建筑能否在以mx为中点的区间看见
bool visable(int i,double mx)
{
//该区间不再建筑的覆盖范围内,直接返回false
if(!cover(i,mx)) return false;
//遍历是否有建筑挡住了第i号建筑
for(int k=0;k<n;k++)
{
//当第k栋建筑y坐标比i建筑小,且高度更高,且k栋建筑同样能在mx区间内看到时,i栋建筑被k栋建筑挡住了。
if(b[k].y<b[i].y&&b[k].h>=b[i].h&&cover(k,mx))
return false;
}
return true;
}
int n,x[maxn*2];
int main()
{
int kase = 0;
while(scanf("%d",&n)==1&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*2] = b[i].x;
x[i*2+1] = b[i].x + b[i].w;
b[i].id = i+1;
}
//对建筑进行排序
sort(b,b+n);
//对建筑的x边界进行排序切割
sort(x,x+2*n);
int m = unique(x,x+2*n)-x;
//如果超过1组数据,那么低二组数据开始要加换行符号
if(kase++) printf("\n");
printf("For map #%d,the visible building are numbered as followed:%d\n",kase,b[0].id);
//遍历每一个建筑
for(int i=0;i<n;i++)
{
//默认状态为不可见
bool vis = false;
//遍历所有区间是否有在某个区间可以看到该建筑
for(int j=0;j<m-1;j++)
{
if(visiable(i,(x[j]+x[j+1])/2))
{
vis = true;
break;
}
}
if(vis)
printf(%d,b[i].id);
}
}
}