建筑物的轮廓问题

问题描述:描述
对于城市中几座建筑外形,给出这些建筑的二维轮廓。
•关于输入
输入的第一行是正整数 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;
			
		}else
			h2=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;
}




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


展开阅读全文

没有更多推荐了,返回首页