2022.4.21 Uva 221

 

 

这个题有一个我认为很有用的思想:离散化。

因为题中给出的坐标不是整数,是无法一个个搜索的,而且会很慢,所以可以记录每个出现的x点,然后取每两个的中点搜索。

每个建筑在该点的只有两种状态,即露出和不会露出。

数据处理上,因为数据保证正确,所以可以忽略掉深度这个数据,只使用高度和x方向,y方向只用于判断前后关系。

#include<cstdio>
#include<algorithm>
#define maxn 105
using namespace std;
struct build
{
int id;
double x,y,w,d,h;
bool operator<(const build &a)const
{
return x<a.x||(x==a.x&&y<a.y);
}
}builds[maxn];
int n,m;
double xsum[maxn*2];
bool isin(int i,double x)
{
return builds[i].x<=x&&builds[i].x+builds[i].w>=x;
}
bool dfs(int i,double x)
{
if(!isin(i,x))
return false;
for(int k=0;k<n;k++)
{
if(isin(k,x)&&builds[k].y<builds[i].y&&builds[k].h>=builds[i].h)//检测每个建筑是否在这点的建筑前并高于它
return false;
}
return true;
}
int main()
{
int kase=0;
while(scanf("%d",&n)&&n)
{
for(int i=0;i<n;i++)
{
scanf("%lf%lf%lf%lf%lf",&builds[i].x,&builds[i].y,&builds[i].w,&builds[i].d,&builds[i].h);
xsum[i*2]=builds[i].x;
xsum[i*2+1]=builds[i].x+builds[i].w;
builds[i].id=i+1;
}
sort(builds,builds+n);
sort(xsum,xsum+2*n);
m=unique(xsum,xsum+n*2)-xsum;//得到去重后的剩余的元素数。去重原理是把重复元素移至数组尾部,需要sort后使用。
if(kase++)
printf("\n");//多组数据换行。
printf("For map #%d, the visible buildings are numbered as follows:\n%d",kase,builds[0].id);
//第一个一定露出来。
for(int i=1;i<n;i++)
{
bool vis=false;
for(int j=0;j<m-1;j++)//遍历每两个x点的中点
{
if(dfs(i,(xsum[j]+xsum[j+1])/2))
{
vis=true;
break;
}
}
if(vis)
{
printf(" %d",builds[i].id);
}
}
printf("\n");
}
return 0;
}

posted @ 2022-04-21 21:27  noname5588  阅读(24)  评论(0)    收藏  举报