sicily 1004之线段判断

本文介绍了一种解决线段重叠问题的算法,并通过具体的实现代码进行了详细说明。面对sicily1004题目的挑战,作者分享了从直觉上的错误尝试到最终正确实现的心路历程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

因为今天中午,不知道为何,sicily服务器挂了,登不上去,ping后发现ip不通,不管它,等他能上了,我再交代码吧

题目是1004,可以百度一下sicily1004,有些博客会黏贴sicily的题目。

这道题是判断线段是否重叠的题目,题目会输入x1, y1, x2, y2,分别是改线段两个端点的坐标。因为线段是直线的一部分,所以最开始我是直接利用这两个坐标算出y=kx+b中的k和b,想着只要k和b一样,那就是重叠了。结果提交上去,WA超多次,我都郁闷了。今天早上才意识到,这是线段,不是直线,既然是线段,就会有端点,那么这道题就要想办法根据这输入的两个点的坐标,设计一个结构来使得接下来的排序啊和判断是否重叠更好的进行。待续,未完,代码就不改了,毕竟还没AC。

答案如下,仅供参考

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;

#define	INF 1e+15
#define EPS 1e-7

inline int dcmp(double a, double b)
{
	if ((a - b) < -EPS) return -1;
	if ((a - b) > EPS) return 1;
	return 0;
}

struct Line
{
	double k, b;
	double pstart, pend;

	Line(double x1, double y1, double x2, double y2)
	{
		if (dcmp(x1, x2) == 0)
		{
			k = INF;
			b = x1;
			pstart = min(y1, y2);
			pend = max(y1, y2);
		}
		else
		{
			k = (y2 - y1) / (x2 - x1);
			b = y1 - k * x1;
			pstart = min(x1, x2);
			pend = max(x1, x2);
		}
	}

};

bool comp(Line a, Line b)
{
	if (dcmp(a.k, b.k) != 0) 
		return dcmp(a.k, b.k) < 0;
	if (dcmp(a.b, b.b) != 0) 
		return dcmp(a.b, b.b) < 0;
	if (dcmp(a.pstart, b.pstart) != 0)
		return dcmp(a.pstart, b.pstart) < 0;
	if (dcmp(a.pend, b.pend) != 0)
		return dcmp(a.pend, b.pend) < 0;
	return false;
}

vector<Line> line;
int n;

int ans()
{
	sort(line.begin(), line.end(), comp);
	int re = n;
	double maxreached = line[0].pend;

	for (int i = 1; i < n; i++)
	{
		if (dcmp(line[i].k, line[i - 1].k) == 0 
			&& dcmp(line[i].b, line[i - 1].b) == 0)
		{
			if (dcmp(line[i].pstart, maxreached) <= 0) re--;
			maxreached = max(maxreached, line[i].pend);
		}
		else
		{
			maxreached = line[i].pend;
		}
	}
	return re;
}



int main()
{
	double x1, x2, y1, y2;
	while (cin >> n && n != 0)
	{
		for (int i = 0; i < n; i++)
		{
			cin >> x1 >> y1 >> x2 >> y2;
			line.push_back(Line(x1, y1, x2, y2));
		}

		cout << ans() << endl;

		line.clear();
	}
	//system("pause");
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值