UVa 221城市正视图(离散化)

https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=157

UVa 221城市正视图(离散化)

题意:输入建筑物的x,y坐标,宽度,深度和高度,输出从南向北看时能看到的建筑物。

这道题需要用到离散化,将所有建筑物物的左右边界坐标存储起来,然后排序去重,那么任意两个相邻x坐标形成的区间要么是可见的,要么就是不可见的。这样只需在这个区间内任选一点(如中点),当该建筑物可见时,首先它的左右边界必须包含这个中点,其次,在它前面不能有比它高的建筑物。

在排序去重时需要用到unique函数,它是c++中的去重函数,但是它不会删除那些重复的函数,而是把它们移到了数组的最后,当需要获得该数组中不重复元素的个数,则是这样的形式unique(x, x + 2*n) - x

 #include<iostream>
#include<algorithm>
#include<string>
#include<cstring>
using namespace std; const int maxn = ; struct Building{
int id;
double x, y, w, d, h;
bool operator < (const Building& rhs) const{
return x < rhs.x || (x == rhs.x && y < rhs.y); //重载<运算符
}
}b[maxn]; int n;
double x[*maxn]; bool solve(int i, double mi)
{
if(!(b[i].x<=mi && b[i].x + b[i].w>=mi)) return false; //该中点不在建筑物b[i]范围内时返回false
for(int k = ; k < n;k++)
{
if (b[k].y<b[i].y && b[k].h >= b[i].h && b[k].x <= mi && b[k].x + b[k].w >= mi) return false;
//若该建筑物前面有建筑物并且高度大于等于该建筑物时,返回false
}
return true;
} int main()
{
int kase = ;
while (cin >> n, n)
{
memset(x, , sizeof(x));
for (int i = ; i < n; i++)
{
cin >> b[i].x >> b[i].y >> b[i].w >> b[i].d >> b[i].h;
b[i].id = i + ;
x[ * i] = b[i].x;
x[ * i + ] = b[i].x + b[i].w;
}
sort(b, b + n); //以重载方法进行排序
sort(x, x + * n);
int m = unique(x, x + *n) - x; //得到不重复的x坐标个数
if(kase++) cout << endl;
cout << "For map #" << kase << ", the visible buildings are numbered as follows:" << endl << b[].id;
for (int i = ; i < n; i++)
{
bool vis = false;
for (int j = ; j < m; j++)
{
if (solve(i, (x[j] + x[j + ]) / )) { vis = true; break; }
}
if (vis == true) cout << " " << b[i].id;
}
cout << endl;
}
return ;
}
上一篇:C#实现对Word文件读写[转]


下一篇:JS:Math 对象方法