5 - 12

//例题5-12 UVa221 Urban Elevations
//1. ordered south-to-north, west-to-east.
int graph[10005][10005];
struct building {
	int x, y, w, d, h;
}b[1005];

bool cmp(const int &n, const int &m) {
	if (b[n].x != b[m].x) return b[n].x < b[m].x;
	else return b[n].y < b[m].y;
}

int main() {
	int n, kases = 1;
	//IN(); OUT();
	while (scanf("%d", &n) && n) {
		vector<int> vis;
		set<int> s;
		CLEAR(graph, 0);
		int left = maxn, down = maxn, right = 0, up = 0;
		for (int k = 1; k <= n; k++) {
			scanf("%d%d%d%d%d", &b[k].x, &b[k].y, &b[k].w, &b[k].d, &b[k].h);
			left = min(left, b[k].x);
			right = max(right, b[k].x + b[k].w);
			down = min(down, b[k].y);
			up = max(up, b[k].y + b[k].d);
			for (int i = b[k].x; i <= b[k].w + b[k].x; i++)
				for (int j = b[k].y; j <= b[k].y + b[k].d; j++)
					graph[i][j] = k;
		}
		for (int i = left; i <= right; i++) {
			int flag = 1, maxh = 0;
			for (int j = down; j <= up; j++) {
				int k = graph[i][j];
				if (flag && k) {
					flag = 0;
					if (!s.count(k)) {
						s.insert(k);
						vis.push_back(k);
					}
					maxh = b[k].h;
				}
				else {
					if (b[k].h > maxh) {
						if (!s.count(k)) {
							s.insert(k);
							vis.push_back(k);
						}
						maxh = b[k].h;
					}
				}
			}
		}
		sort(vis.begin(), vis.end(), cmp);
		if (kases != 1) puts("");
		printf("For map #%d, the visible buildings are numbered as follows:\n", kases++);
		int flag = 1;
		for (int i = 0; i < vis.size(); i++) {
			if (flag) flag = 0;
			else printf(" ");
			printf("%d", vis[i]);
		}
		puts("");
	}
	return 0;
}


//离散化,我自己的实现是暴力搜索所有位置,只要把x坐标排序去重,就可以化连续区间为区间上的点
int n, kase = 0;
struct Buildings {
	int id;
	double x, y, w, d, h;
	bool operator<(const Buildings &rhs) {
		if (rhs.x != x) return x < rhs.x;
		else return y < rhs.y;
	}
}b[1005];

bool cover(const Buildings &bu, int x) {
	return bu.x <= x && bu.x + bu.w >= x;
}

bool visible(const Buildings &bu, int x) {
	if (!cover(bu, x)) return false;
	for (int i = 0; i < n; i++)
		if (b[i].y < bu.y && cover(b[i], x) && b[i].h >= bu.h) return false;
	return true;
}

int main() {
	int x[1005];
	while (scanf("%d", &n) && n) {
		for (int i = 0; i < n; i++) {
			b[i].id = i + 1;
			scanf("%lf%lf%lf%lf%lf", &b[i].x, &b[i].y, &b[i].w, &b[i].d, &b[i].h);
			x[2 * i] = b[i].x;
			x[2 * i + 1] = b[i].x + b[i].w;
		}
		sort(b, b + n);
		sort(x, x + 2*n);
		int m = unique(x, x + 2 * n) - x;
		if (kase) puts("");
		printf("For map #%d, the visible buildings are numbered as follows:\n%d", ++kase, b[0].id);
		for (int i = 1; i < n; ++i) {
			bool vis = false;
			for (int j = 0; j < m-1; ++j) {
				int xx = (x[j] + x[j + 1]) / 2;
				if (visible(b[i], xx)) { vis = true; break; }
			}
			if (vis) printf(" %d", b[i].id);
		}
		puts("");
	}
	return 0;
}
//学了重载运算符感觉把小于号定义在结构体中比较好
//unique():it cannot alter the size of an array or a container
//The relative order of the elements not removed is preserved, 
//while the elements between the returned iterator and last are left in a valid but unspecified state.
//returning an iterator to the element that should be considered its new past-the-end element.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值