pku 1048 Fishnet 叉积求交点 + 叉积求多边形面积
http://poj.org/problem?id=1408
题意是给定一个1*1的方格,然后每个边有n个点,然后连线求交织出来的四边的最大面积。
首先利用叉积求出所有的交点,(注意边界点单独处理),然后循环遍历所有的四边形求面积。取最大即可。
#include <iostream> #include <cstdio> #include <cstring> #define maxn 33 using namespace std; const double eps = 1e-8; double a[maxn],b[maxn],c[maxn],d[maxn]; struct point { double x,y; point(double a = 0,double b = 0): x(a),y(b){} }p[maxn][maxn]; int n; int dblcmp(double x) { if (x > eps) return 1; else if (x < -eps) return -1; else return 0; } double det(double x1,double y1,double x2,double y2) { return x1*y2 - x2*y1; } double cross(point ta,point tb,point tc) { return det(tb.x - ta.x,tb.y - ta.y,tc.x - ta.x, tc.y - ta.y); } //叉积求交点 point segcross(point xa, point xb, point xc, point xd) { double s1, s2; int d1, d2, d3, d4; point po(0,0); d1 = dblcmp(s1 = cross(xa, xb, xc)); d2 = dblcmp(s2 = cross(xa, xb, xd)); d3 = dblcmp(cross(xc, xd, xa)); d4 = dblcmp(cross(xc, xd, xb)); po.x = (xc.x*s2 - xd.x*s1)/(s2 - s1); po.y = (xc.y*s2 - xd.y*s1)/(s2 - s1); return po; } //叉积求多边形面积 double getsum(point ta,point tb,point tc,point td) { double s = 0; s += det(ta.x,ta.y,tb.x,tb.y); s += det(tb.x,tb.y,tc.x,tc.y); s += det(tc.x,tc.y,td.x,td.y); s += det(td.x,td.y,ta.x,ta.y); return s*0.5; } int main() { int i,j; while (~scanf("%d",&n)) { if (!n) break; for (i = 1; i <= n; ++i) scanf("%lf",&a[i]); for (i = 1; i <= n; ++i) scanf("%lf",&b[i]); for (i = 1; i <= n; ++i) scanf("%lf",&c[i]); for (i = 1; i <= n; ++i) scanf("%lf",&d[i]); //左右两个边界处理一下 for (j = 0; j <= n + 1; ++j) { if (j == 0) { p[0][j].x = p[0][j].y = 0; p[n + 1][j].x = 1; p[n + 1][j].y = 0; } else if (j == n + 1) { p[0][j].x = 0; p[0][j].y = 1; p[n + 1][j].x = p[n + 1][j].y = 1; } else { p[0][j].x = 0; p[0][j].y = c[j]; p[n + 1][j].x = 1; p[n + 1][j].y = d[j]; } } //上下两个边界处理一下 for (i = 1; i <= n; ++i) { p[i][0].x = a[i]; p[i][0].y = 0; p[i][n + 1].x = b[i]; p[i][n + 1].y = 1; } //循环求交点 for (i = 1; i <= n; ++i) { for (j = 1; j <= n; ++j) { point xa(a[i],0); point xb(b[i],1); point xc(0,c[j]); point xd(1,d[j]); p[i][j] = segcross(xa,xb,xc,xd); } } /* for (i = 0; i <= n + 1; ++i) { for (j = 0; j <= n + 1; ++j) { printf("%d %d %.3lf %.3lf\n",i,j,p[i][j].x,p[i][j].y); } }*/ //循环遍历四边形求面积 double ans = -99999999.0; for (i = 1; i <= n + 1; ++i) { for (j = 1; j <= n + 1; ++j) { double sum = getsum(p[i][j - 1],p[i][j],p[i - 1][j],p[i - 1][j - 1]); if (dblcmp(sum - ans) > 0) ans = sum; } } printf("%.6lf\n",ans); } return 0; }