【数学】从上往下看,打印数轴上看到的颜色

题目:EPI



//把Endpoint和LineSegment分开,是为了点的排序
class LineSegment
{
public:
	int left, right;
	int height;
	int color;
	LineSegment(int l, int r, int c, int h):left(l), right(r), color(c), height(h){}
	const bool operator<(const LineSegment &a)const
	{
		return height < a.height;
	}
};


class Endpoint
{
public:
	bool Isleft;
	//之所以把L设为const,是为了 E.emplace_back(true, &A[i]); 这行代码能编译通过
	//&A[i]是const LineSegment*
	const LineSegment* L;
	Endpoint(bool isleft, const LineSegment* line) :Isleft(isleft), L(line){}
	
	const bool operator<(const Endpoint &a)const
	{
		return val() < a.val();
	}

	const int val()const
	{
		if (Isleft)
			return L->left;
		else
			return L->right;
	}
};



void print_color_from_above(const vector<LineSegment> &A)
{
	if (A.empty())
		return;
	vector<Endpoint> E;
	for (int i = 0; i < A.size(); i++)
	{
		E.emplace_back(true, &A[i]);
		E.emplace_back(false, &A[i]);
	}
	sort(E.begin(), E.end());

	int prev_xaxis;
	shared_ptr<LineSegment> prev = nullptr;
	//注意T的第二个参数必须有const
	map<int,const LineSegment*> T;//第一个参数int是高度height,按照height从低到高排序
	for (int i = 0; i < E.size(); i++)
	{
		Endpoint e =E[i];
		if (!T.empty() && prev_xaxis != e.val())//Endpoint在x轴上有可能相等
		{
			if (prev == nullptr)//第一个LineSegment
				prev = shared_ptr<LineSegment>(new LineSegment(prev_xaxis, e.val(), T.crbegin()->second->color, T.crbegin()->second->height));
			else
			{
				//T.crbegin()是T中高度最高的那条直线,crbegin()相当于 (end()-1),即倒数第一个记录
				if (prev->color == T.crbegin()->second->color && prev->height == T.crbegin()->second->height)
					prev->right = e.val();
				else
				{
					//打印
					cout << "[" << prev->left << "," << prev->right << "]" << ",color=" << prev->color << ",height=" << prev->height << endl;
					//更新prev
					*prev = LineSegment(prev_xaxis, e.val(), T.crbegin()->second->color, T.crbegin()->second->height);
				}
			}
		}

		prev_xaxis = e.val();
		if (e.Isleft)
			T.emplace(e.L->height, e.L);
		else
			T.erase(e.L->height);

	}
	if (prev)
		cout << "[" << prev->left << "," << prev->right << "]" << ",color=" << prev->color << ",height=" << prev->height << endl;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值