zoj 1460 The Partition of a Cake

#include<iostream>
#include<stdlib.h>
#include<math.h>
#include<algorithm>
#define eps 1e-9
using namespace std;

bool eq(double num1, double num2) {
	return fabs(num1 - num2) < eps ? true : false;
}

struct point {
	double x, y;
	point() {};
	point(double x, double y): x(x), y(y) {};
	point operator -(point p) {
		return point(x - p.x, y - p.y);
	}

	double operator *(point p) {
		return x * p.y - y * p.x;
	}

	double operator ==(point p) {
		return (eq(x, p.x) && eq(y, p.y));
	}

	void sc() {
		scanf("%lf%lf", &x, &y);
	}

} pts[100];

double getdis(point p1, point p2) {
	return sqrt((p2.x - p1.x) * (p2.x - p1.x) + (p2.y - p1.y) * (p2.y - p1.y));
}


struct seg {
	point p1, p2;
	seg() {};
	seg(point p1, point p2): p1(p1), p2(p2) {};

	int jc(seg se, point &pt) {
		point p3 = se.p1;
		point p4 = se.p2;
		if (min(p1.x, p2.x) <= max(p3.x, p4.x) && min(p3.x, p4.x) <= max(p1.x, p2.x) &&
		        min(p1.y, p2.y) <= max(p3.y, p4.y) && min(p3.y, p4.y) <= max(p1.y, p2.y)) {
			double k1, k2, k3, k4;
			k1 = (p4 - p1) * (p2 - p1);
			k2 = (p2 - p1) * (p3 - p1);
			k3 = (p1 - p4) * (p3 - p4);
			k4 = (p3 - p4) * (p2 - p4);

			if (k1 * k2 > 0 && k3 * k4 > 0) { //这里不能允许=0的情况 因为如果=0相交的端点必然在原蛋糕的4条边上。
											  //所以那个端点不会产生新的块
				double d1 = fabs(k2) / getdis(p1, p2);
				double d2 = fabs(k1) / getdis(p1, p2);
				double t = d1 / (d1 + d2);
				point p = p4 - p3;
				pt.x = p.x * t + p3.x;
				pt.y = p.y * t + p3.y;
				//以上为两线段求交点的计算几何方法。
				//https://blog.csdn.net/qq_45660232/article/details/121276405 这是我使用的方法的详解
				return 1;
			}
			return 0;
		}
		return 0;
	}

	bool operator==(seg s1) {
		return (p1 == s1.p1 && p2 == s1.p2) || (p1 == s1.p2 && p2 == s1.p1);
	}

} segs[20];


int main() {
	int n, i, j, ans, x, k;
	while (scanf("%d", &n) && n) {
		ans = 1;
		for (i = 0; i < n; i++) {
			segs[i].p1.sc();
			segs[i].p2.sc();
			k = 0;
			for (j = 0; j < i; j++) {
				if (segs[i] == segs[j])break;
			}
			if (j != i) continue;

			for (j = 0; j < i; j++) {
				point p;
				if (segs[i].jc(segs[j], p)) {
					for (x = 0; x < k; x++) {
						if (pts[x] == p)break;
					}
					if (x != k)continue;
					pts[k++] = p;
				}
			}
			ans += k + 1;
		}
		cout << ans << endl;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值