ZOJ 1683 求平面上直线交点 & 求任意四边形面积

133 篇文章 17 订阅

ZOJ Problem Set - 1683

题目大意:

在1*1的正方形格子上给出每边的两个点,按顺序连接对边的点,求这样形成的一系列四边形中最大的面积。

思路:

1. 求交点

      见函数GetCrossPoint (http://blog.csdn.net/abcjennifer/article/details/7584628)

2. 求面积

      四边形面积可由两个三角形面积相加而得,这里使用叉积,因为三角形的两个向量边叉乘的结果为其所形成的平行四边形面积,所以三角形面积为1/2×向量边1 x 向量边2

      见函数GetArea()


Code:

#include"iostream"
#include"stdio.h"
#include"math.h"
using namespace std;

#define N 40
int n;

struct Point {
	double x;
	double y;
} pset[N + 1][N + 1];

struct Line {
	void L(Point pp1, Point pp2) {
		p1 = pp1;
		p2 = pp2;
	}
	Point p1, p2;
	double a, b, c;
} lineset[N][N];

void GetLinePara(Line *l) {
	l->a = l->p1.y - l->p2.y;
	l->b = l->p2.x - l->p1.x;
	l->c = l->p1.x * l->p2.y - l->p2.x * l->p1.y;
}

Point GetCrossPoint(Line *l1, Line *l2) {
	GetLinePara(l1);
	GetLinePara(l2);
	double D = l1->a * l2->b - l2->a * l1->b;
	Point p;
	p.x = (l1->b * l2->c - l2->b * l1->c) / D;
	p.y = (l1->c * l2->a - l2->c * l1->a) / D;
	return p;
}

double Xmult(Point a, Point b, Point c)//get vector ac and bc
{
	return (c.x - a.x) * (c.y - b.y) - (c.y - a.y) * (c.x - b.x);
}

double GetArea(int i, int j) {
	double area1 = Xmult(pset[i][j], pset[i + 1][j], pset[i + 1][j + 1]) / 2;
	double area2 = Xmult(pset[i][j], pset[i][j + 1], pset[i + 1][j + 1]) / 2;
	return fabs(area1) + fabs(area2);
}

void Init_Points() {
	int i;
	for (i = 1; i <= n; i++)
		scanf("%lf", &pset[i][0].x), pset[i][0].y = 0;
	for (i = 1; i <= n; i++)
		scanf("%lf", &pset[i][n + 1].x), pset[i][n + 1].y = 1;
	for (i = 1; i <= n; i++)
		scanf("%lf", &pset[0][i].y), pset[0][i].x = 0;
	for (i = 1; i <= n; i++)
		scanf("%lf", &pset[n + 1][i].y), pset[n + 1][i].x = 1;

	pset[0][0].x = pset[0][0].y = 0;
	pset[n + 1][0].x = 1, pset[n + 1][0].y = 0;
	pset[0][n + 1].x = 0, pset[0][n + 1].y = 1;
	pset[n + 1][n + 1].x = pset[n + 1][n + 1].y = 1;
}

void Init_Lines() {
	int i, j;
	Line l1, l2;
	for (i = 1; i <= n; i++) {
		for (j = 1; j <= n; j++) {
			l1.L(pset[i][0], pset[i][n + 1]);
			l2.L(pset[0][j], pset[n + 1][j]);
			pset[i][j] = GetCrossPoint(&l1, &l2);
		}
	}
}

int main() {
	int i, j;
	while (cin >> n&&n) {
		Init_Points();
		Init_Lines();
		double maxarea = 0;
		double area;
		for (i = 0; i < n + 1; i++)
			for (j = 0; j < n + 1; j++) {
				area = GetArea(i, j);
				maxarea = area > maxarea ? area : maxarea;
			}
		printf("%lf\n", maxarea);
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值