POJ 2451 (半平面交 板子题)
来源:互联网 发布:零食店铺推荐知乎 编辑:程序博客网 时间:2024/05/29 19:27
题目链接:点击这里
题意: 给出n个半平面, 求出半平面交和一个矩形的面积交。
检验一发板子.
#include <cstdio>#include <cmath>#include <algorithm>#include <iostream>#include <vector>using namespace std;#define maxn 100005const double eps = 1e-7;const double INF = 1e20;const double pi = acos (-1.0);int dcmp (double x) { if (fabs (x) < eps) return 0; return (x < 0 ? -1 : 1);}inline double sqr (double x) {return x*x;}//*************点struct Point { double x, y; Point (double _x = 0, double _y = 0):x(_x), y(_y) {} void input () {scanf ("%lf%lf", &x, &y);} void output () {printf ("%.2f %.2f\n", x, y);} bool operator == (const Point &b) const { return (dcmp (x-b.x) == 0 && dcmp (y-b.y) == 0); } bool operator < (const Point &b) const { return (dcmp (x-b.x) == 0 ? dcmp (y-b.y) < 0 : x < b.x); } Point operator + (const Point &b) const { return Point (x+b.x, y+b.y); } Point operator - (const Point &b) const { return Point (x-b.x, y-b.y); } Point operator * (double a) { return Point (x*a, y*a); } Point operator / (double a) { return Point (x/a, y/a); } double len2 () {//返回长度的平方 return sqr (x) + sqr (y); } double len () {//返回长度 return sqrt (len2 ()); } Point change_len (double r) {//转化为长度为r的向量 double l = len (); if (dcmp (l) == 0) return *this;//零向量返回自身 r /= l; return Point (x*r, y*r); } Point rotate_left () {//顺时针旋转90度 return Point (-y, x); } Point rotate_right () {//逆时针旋转90度 return Point (y, -x); } Point rotate (Point p, double ang) {//绕点p逆时针旋转ang Point v = (*this)-p; double c = cos (ang), s = sin (ang); return Point (p.x + v.x*c - v.y*s, p.y + v.x*s + v.y*c); } Point normal () {//单位法向量 double l = len (); return Point (-y/l, x/l); }};double cross (Point a, Point b) {//叉积 return a.x*b.y-a.y*b.x;}double dot (Point a, Point b) {//点积 return a.x*b.x + a.y*b.y;}double dis (Point a, Point b) {//两个点的距离 Point p = b-a; return p.len ();}double rad_degree (double rad) {//弧度转化为角度 return rad/pi*180;}double rad (Point a, Point b) {//两个向量的夹角 return fabs (atan2 (fabs (cross (a, b)), dot (a, b)) );}bool parallel (Point a, Point b) {//向量平行 double p = rad (a, b); return dcmp (p) == 0 || dcmp (p-pi) == 0;}//************直线 线段struct Line { Point s, e;//直线的两个点 double k;//极角 Line () {} Line (Point _s, Point _e) { s = _s, e = _e; k = atan2 (e.y - s.y,e.x - s.x); } //一个点和倾斜角确定直线 Line (Point p, double ang) { k = ang; s = p; if (dcmp (ang-pi/2) == 0) { e = s + Point (0, 1); } else e = s + Point (1, tan (ang)); } void input () { s.input (); e.input (); } void adjust () { if (e < s) swap (e, s); } double length () {//求线段长度 return dis (s, e); } void get_angle () { k = atan2 (e.y - s.y,e.x - s.x); } double angle () {//直线的倾斜角 if (dcmp (k) < 0) k += pi; if (dcmp (k-pi) == 0) k -= pi; return k; } Point operator &(const Line &b)const {//直线的交点(保证存在) Point res = s; double t = (cross (s - b.s, b.s - b.e))/cross (s - e, b.s - b.e); res.x += (e.x - s.x)*t; res.y += (e.y - s.y)*t; return res; }};double polygon_area (Point *p, int n) { //n个点 double area = 0; for (int i = 1; i < n-1; i++) { area += cross (p[i]-p[0], p[i+1]-p[0]); } return area/2;}bool HPIcmp (const Line &a, const Line &b) { if (fabs(a.k - b.k) > eps) return a.k < b.k; return cross (a.s - b.s, b.e - b.s) < 0; }Line Q[maxn];void HPI(Line line[], int n, Point res[], int &resn) { int tot = n; sort(line,line+n,HPIcmp); tot = 1; for(int i = 1;i < n;i++){ if(fabs(line[i].k - line[i-1].k) > eps) line[tot++] = line[i]; } int head = 0, tail = 1; Q[0] = line[0]; Q[1] = line[1]; resn = 0; for (int i = 2; i < tot; i++) { if (fabs(cross (Q[tail].e-Q[tail].s, Q[tail-1].e-Q[tail-1].s)) < eps || fabs(cross (Q[head].e-Q[head].s, Q[head+1].e-Q[head+1].s)) < eps) return; while(head < tail && (cross ((Q[tail]&Q[tail-1])-line[i].s, line[i].e-line[i].s)) > eps) tail--; while(head < tail && (cross ((Q[head]&Q[head+1]) - line[i].s, line[i].e-line[i].s)) > eps) head++; Q[++tail] = line[i]; } while(head < tail && (cross ((Q[tail]&Q[tail-1]) - Q[head].s, Q[head].e-Q[head].s)) > eps) tail--; while(head < tail && (cross ((Q[head]&Q[head-1]) -Q[tail].s, Q[tail].e-Q[tail].e)) > eps) head++; if(tail <= head + 1) return; for(int i = head; i < tail; i++) res[resn++] = Q[i]&Q[i+1]; if(head < tail - 1) res[resn++] = Q[head]&Q[tail];}int n, m;Point ans[maxn];Line hp[maxn];int main () { while (cin >> n) { for (int i = 0; i < n; i++) { hp[i].input (); hp[i].get_angle (); } hp[n++] = Line (Point (0, 0), Point (10000, 0)); hp[n++] = Line (Point (10000, 0), Point (10000, 10000)); hp[n++] = Line (Point (10000, 10000), Point (0, 10000)); hp[n++] = Line (Point (0, 10000), Point (0, 0)); HPI (hp, n, ans, m); if (m) { printf ("%.1f\n", polygon_area (ans, m)); } else printf ("0.0\n"); } return 0;}
0 0
- POJ 2451 (半平面交 板子题)
- 旋转卡壳+半平面交板子 poj 2079
- 【poj 2451】半平面交
- poj 2451 (半平面求交)
- poj 2451 半平面交模板
- POJ 3525 半平面交
- POJ 3384 半平面交
- POJ 1755 半平面交
- POJ 2540 半平面交
- poj 3335(半平面交)
- POJ 3525 半平面交
- 半平面交 (POJ 1279
- [POJ]3525 半平面交
- POJ 2451 Uyuw's Concert(半平面交nlgn)
- POJ 2451 Uyuw's Concert(半平面交)
- poj 2451 Uyuw's Concert - 半平面交
- POJ 2451 Uyuw's Concert 半平面交O(nlogn)
- POJ 2451 Uyuw's Concert(半平面交求面积)
- CentOs7 安装Tengine 并设置成系统服务,开机自动启动。
- 访问第三方应用
- CentOS 安装lnmp环境
- 【Shiro】Apache Shiro架构之自定义realm
- Android MediaPlayer
- POJ 2451 (半平面交 板子题)
- from表单传值到页面,并在iframe中显示该页面,通过form的target属性指定iframe
- el表达式获取url中文参数乱码
- http协议
- slua学习记录(一)
- ReboundScrollView 仿IOS 拖拽回弹
- vs2010编译最新live555
- Android代码混淆
- 文件系统的安全性