建筑物的轮廓问题

来源:互联网 发布:知乎日报启动画面 编辑:程序博客网 时间:2024/06/02 09:13
问题描述:描述
对于城市中几座建筑外形,给出这些建筑的二维轮廓。
•关于输入
输入的第一行是正整数 n(1<= n <=100 000),表示建筑的数目。
接下来 n 行,每行三个正整数start end height,表示建筑的左边界、右边界和高度。
•关于输出
输出建筑群的轮廓,包含多行,从左到右输出建筑的边界:(U|D|R) len

U、D、R分别表示上、下、右,即建筑边界延伸的方向,len为正整数,表示边界在此方向上延伸的长度。

算法:

建筑物轮廓合并伪代码
r = new Line; x = 0; y = 0; pre = -1;
while (p.s < INF || q.s < INF) { // 判断是否合并完成
r.s = (p.s <= q.s) ? p.s : q.s; // 找最先的转折点
if (r.s == p.s) { // 第一条轮廓线的高度变化
x = p.h; p = p.next;
}
if (r.s == q.s) { // 第二条轮廓线的高度变化
y = q.h; q = q.next;
}
r.h = (x >= y) ? x : y; // 取较高的轮廓
if (r.h != pre) { // 只有高度与之前不同才是一个新转折点
pre = r.h;
r.next = new Line;
r = r.next;
}
}
r.s = INF;
建筑轮廓问题

以上参考了汪小林 分治法的建筑物轮廓问题,归并排序类似用了分治法。上面算法有些地方没有考虑到那样的细致

如下我的代码:

// 轮廓问题1.cpp : 定义控制台应用程序的入口点。//// 轮廓.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include <iostream>#include <vector>#define INF  0xffff//表示无穷大using namespace std;/*建筑物的轮廓问题author:surpassgood数据结构:用 NODE 表示转折点*/template <class T>class NODE {public:T x;//x 方向坐标T h;//高度public:NODE(){x=0;h=0;}NODE(T x1,T h1){x=x1;h=h1;}bool operator<(const NODE &other)const//按x排序的时候能用到{return x<other.x;}friend ostream& operator << <T> (ostream& os, const NODE<T> & ob);friend void fun1(vector< NODE< T> > line_1,vector<NODE< T> > line_2,vector< NODE< T> > &result);};template <class T>ostream& operator << (ostream& os, const  NODE<T> & ob){cout<<"x-->"<<ob.x<<"    h--->"<<ob.h<<endl;return os;}//合并 用函数模板void fun1(vector< NODE< double> > line_1,vector<NODE< double> > line_2,vector< NODE< double> > &result){NODE< double> *r=new NODE<double>();vector< NODE<double> > ::iterator it_1=line_1.begin();vector< NODE<double> > ::iterator it_2=line_2.begin();it_1=it_1+1;it_2=it_2+1;double h1,h2;//分别对应line_1  line_2的转折点  高度double pre_1=0,pre_2=0;double pre=-1;for (;((*it_1).x<INF)&&((*it_2).x<INF);){r->x=(*it_1).x<(*it_2).x?(*it_1).x:(*it_2).x;if(r->x==(*it_1).x){h1=(*it_1).h;pre_1=h1;}else{h1=pre_1;}if(r->x==(*it_2).x){h2=(*it_2).h;pre_2=h2;}elseh2=pre_2;r->h=h1>h2?h1:h2;if(r->x==(*it_1).x)++it_1;//注意不能在for只有写出 it_1++ it_2++if(r->x==(*it_2).x)++it_2;if(r->h!=pre)//和之前的高度不同 要改变高度{result.push_back(*r);pre=r->h;r=new NODE<double>;}}/*后续的调整*/if((*it_2).x<INF){while(it_2!=line_2.end()){result.push_back(NODE <double>((*it_2).x,(*it_2).h));it_2++;}}else if((*it_1).x<INF){while(it_1!=line_1.end()){result.push_back(NODE <double>((*it_1).x,(*it_1).h));it_1++;}}else//最后一个转折点为(INF,0)result.push_back(NODE<double >(INF,0));/*打印结果看下*/vector< NODE<double> > ::iterator iter;for (iter = result.begin(); iter != result.end(); ++iter){std::cout << *iter;}}double min(double x,double y){return x<y?x:y;}int _tmain(int argc, _TCHAR* argv[]){vector<NODE<double> > line_1,line_2,result;NODE<double> first(-INF,0);//开始的转折点/*测试用的*/line_1.push_back(first);line_2.push_back(first);result.push_back(first);line_1.push_back( NODE<double>(1,2));line_1.push_back(NODE<double>(3,0));line_1.push_back( NODE<double>(INF,0));line_2.push_back( NODE<double>(2,6));line_2.push_back( NODE<double>(4,0));line_2.push_back (NODE<double>(INF,0));fun1(line_1,line_2,result);return 0;}


写代码和写文章相似,要思路清晰,算法要搞清楚。越来发现,算法是关键


原创粉丝点击