Sicily 1004. I Conduit!

本文介绍了一种处理线段交集问题的算法,包括如何通过自定义比较函数对线段进行排序,并且详细解释了如何判断不同线段是否位于同一直线上,以及在同一直线上的线段如何计算交集数量。

题目链接在此

参考的是这位大神的解题方法

这题要考虑的情况有很多。

另外两个double类型数据不能简单地以==来判断相等!


以下是源代码:

#include<iostream>
#include<cmath>
#include<algorithm>

using namespace std;

#define INFINITE 10000.00

bool equal(double a, double b) {  //两个double类型数据不能简单地以==来判断相等
	return fabs(a - b) < 1e-6;
}

struct line {
	double k, b;
	double x1, y1, x2, y2;

	line() {}
	line(double xx1, double yy1, double xx2, double yy2, double kk, double bb)
		: x1(xx1), y1(yy1), x2(xx2), y2(yy2), k(kk), b(bb) {}

	//  对线段(x1,y1)-(x2,y2)转化成 y=kx+b 形式,进行排序,按照 k 升序排序,如果 k 值相等,则按 b 值升序排序,
	//  如果 k,b都相等,则按 x1 升序排序,若 x1 还相等的话,则按 x2 升序排序。
	//  要对 平行于 y轴,即斜率不存在的线段 加以判断,
	//  先按照 b 值(b==x1)升序排序,再按 y1 升序排序,最后按 y2 升序排序
	bool operator<(const line& other) const{ //  自定义比较函数
		if (equal(k, other.k)){
			if (equal(k, INFINITE)) {
				if (equal(b, other.b)) {
					if (equal(y1, other.y1))
						return y2 < other.y2;
					else
						return y1 < other.y1;
				}
				else
					return b < other.b;
			}
			else if (equal(b, other.b)) {
				if (x1 == other.x1)
					return x2 < other.x2;
				else
					return x1 < other.x1;
			}
			else
				return b < other.b;
		}
		else
			return k<other.k;
	}
} s[10000];

int main() {
	int lineNum;
	double x1, y1, x2, y2;
		
	while (cin >> lineNum && lineNum != 0) {
		for (int i = 0; i < lineNum; i++) {
			cin >> x1 >> y1 >> x2 >> y2;
			if (x1 > x2 || (equal(x1, x2) && y1 > y2)) {  //保证x1<x2或斜率不存在时有y1<y2
				swap(x1, x2); 
				swap(y1, y2); 
			}

			if (equal(x1, x2))
				s[i] = line(x1, y1, x2, y2,INFINITE,x1);
			else {
				s[i] = line(x1, y1, x2, y2, (y2 - y1) / (x2 - x1), 0);
				s[i].b = y1 - s[i].k * x1;
			}
		}

		sort(s, s + lineNum);

		int counter = 1;
		double farX = s[0].x2, farY = s[0].y2;  //(farX,farY)记录当前线段的终点
		for (int i = 1; i < lineNum; i++) {
			//如果k 或者b 不相等,则肯定不在同一直线上
			if (!equal(s[i].k, s[i - 1].k) || !equal(s[i].b, s[i - 1].b)) {
				farX = s[i].x2;
				farY = s[i].y2;
				counter++;
			}
			//在同一直线上但没有公共部分
			else if ((s[i].k != INFINITE && s[i].x1 > farX) || (s[i].k == INFINITE && s[i].y1 > farY)) {
				farX = s[i].x2;
				farY = s[i].y2;
				counter++;
			}
			//在同一直线上而且有公共部分,如果当前线段的终点更远,那也要更新(x,y)
			else if ((s[i].k != INFINITE && farX < s[i].x2) || (s[i].k == INFINITE && farY < s[i].y2)) {
				farX = s[i].x2;
				farY = s[i].y2;
			}
		}

		cout << counter << endl;
	}

	return 0;
}


传送带损坏与对象检测数据集 一、基础信息 • 数据集名称:传送带损坏与对象检测数据集 • 图片数量: 训练集:645张图片 验证集:185张图片 测试集:92张图片 总计:922张工业监控图片 • 训练集:645张图片 • 验证集:185张图片 • 测试集:92张图片 • 总计:922张工业监控图片 • 分类类别: Hole(孔洞):传送带表面的孔洞损坏。 Human(人类):工作区域中的人类,用于安全监控。 Other Objects(其他对象):非预期对象,可能引起故障。 Puncture(刺穿):传送带被刺穿的损坏。 Roller(滚筒):传送带滚筒部件。 Tear(撕裂):传送带撕裂损坏。 impact damage(冲击损坏):由于冲击导致的损坏。 patch work(修补工作):已修补的区域。 • Hole(孔洞):传送带表面的孔洞损坏。 • Human(人类):工作区域中的人类,用于安全监控。 • Other Objects(其他对象):非预期对象,可能引起故障。 • Puncture(刺穿):传送带被刺穿的损坏。 • Roller(滚筒):传送带滚筒部件。 • Tear(撕裂):传送带撕裂损坏。 • impact damage(冲击损坏):由于冲击导致的损坏。 • patch work(修补工作):已修补的区域。 • 标注格式:YOLO格式,包含边界框和类别标签,适用于目标检测任务。 • 数据格式:图像数据来源于工业监控系统,适用于计算机视觉分析。 二、适用场景 • 工业自动化检测系统开发:用于构建自动检测传送带损坏和异物的AI模型,实现实时监控和预防性维护,减少停机时间。 • 安全监控应用:识别人类和其他对象,提升工业环境的安全性,避免事故和人员伤害。 • 学术研究与创新:支持计算机视觉在制造业、物流和自动化领域的应用研究,促进AI技术与工业实践的融合。 • 教育与培训:可用于培训AI模型或作为工业工程和自动化教育的案例数据,帮助学习者理解实际应用场景。 三、数据集优势 • 多样化的类别覆盖:包含8个关键类别,涵盖多种损坏类型和对象,确保模型能够处理各种实际工业场景,提升泛化能力。 • 精准的标注质量:采用YOLO格式,边界框标注准确,由专业标注人员完成,保证数据可靠性和模型训练效果。 • 强大的任务适配性:兼容主流深度学习框架(如YOLO、TensorFlow、PyTorch),可直接用于目标检测任务,并支持扩展至其他视觉任务需求。 • 突出的工业价值:专注于工业传送带系统的实际需求,帮助提升生产效率、降低维护成本,并增强工作场所安全,具有较高的实际应用价值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值