URAL 1464 Light
来源:互联网 发布:mac hosts文件位置 编辑:程序博客网 时间:2024/06/05 19:48
在一个简单多边形内有一个灯泡,问灯泡能够照到的面积。我是看了封尘记忆的blog的,大概理解了。
主要看这个图,然后和代码结合起来看。。多边形是ABCDE,因为EA边跨过了x轴负半轴,所以多添加一个在负半轴上的点M。扫描线扫过去阴影部分面积答案加起来就好了。
扫描线有一条入点和一个出点,point里面有重载小于号,是保证入点的极角小于出点的极角。seg重载小于号,新插入的线段必须得跟已经插入的线段,按照到原点的距离排序。然后就是用multiset。。
#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <cmath>#include <set>#include <vector>using namespace std;#define LL long long#define eps 1e-8#define inf 0x3f3f3f3f#define Pi acos( -1.0 )#define pb push_back#define mnx 60100#define mxn 200int dcmp( double x ){ if( fabs( x ) < eps ) return 0; return x < 0 ? -1 : 1;}struct point{ double x, y, ang; point( double x = 0, double y = 0 ) : x(x), y(y) { ang = atan2( y, 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 * ( const double &k ) const{ return point( x * k, y * k ); } point operator / ( const double &k ) const{ return point( x / k, y / k ); } bool operator < ( const point &b ) const{ return ang > b.ang; } bool operator == ( const point &b ) const{ return dcmp( x - b.x ) == 0 && dcmp( y - b.y ) == 0; } double len(){ return sqrt( x * x + y * y ); }};typedef point Vector;double dot( Vector a, Vector b ){ return a.x * b.x + a.y * b.y;}double cross( Vector a, Vector b ){ return a.x * b.y - a.y * b.x;}point get_intersection( point au, point av, point bu, point bv ){ Vector u = au - bu, aV = av - au, bV = bv - bu; double t = cross( bV, u ) / cross( aV, bV ); return au + aV * t;}const point o = point( 0, 0 );point base;struct Seg{ point u, v; int id, in; double ang; Seg(){} Seg( point u, point v, int in, int id, double ang ) : u(u), v(v), in(in), id(id), ang(ang) {} bool operator < ( const Seg &b ) const { if( u == b.u ){ return cross( v - u, b.v - u ) < 0; } point aa = get_intersection( u, v, o, base ); point bb = get_intersection( b.u, b.v, o, base ); return aa.len() < bb.len(); }}L[mnx<<1];bool cmp( const Seg &a, const Seg &b ){ return a.ang < b.ang || ( a.ang == b.ang && a.in > b.in );}int n, all;point p[mnx];void add( point a, point b, int kk ){ if( a < b ) swap( a, b ); L[all++] = Seg( a, b, 1, kk, a.ang ); L[all++] = Seg( b, a, 0, kk, b.ang );}double cal( const Seg &seg, double pre, double now ){ point aa = get_intersection( seg.u, seg.v, o, point( cos(pre), sin(pre) ) ); point bb = get_intersection( seg.u, seg.v, o, point( cos(now), sin(now) ) ); return fabs( 0.5 * cross( aa, bb ) );}multiset<Seg> S;multiset<Seg>::iterator itArr[mnx<<1];void solve(){ S.clear(); double ans = 0, pre = -Pi; for( int i = 0; i < all; ++i ){ double nowAng = L[i].ang; base = L[i].u; if( L[i].in ){ if( !S.empty() ) ans += cal( *S.begin(), pre, nowAng ); itArr[L[i].id] = S.insert( L[i] ); } else{ ans += cal( *S.begin(), pre, nowAng ); S.erase( itArr[L[i].id] ); } pre = nowAng; } printf( "%.10lf\n", ans );}int main(){ //freopen( "out.txt", "w", stdout ); point c; while( scanf( "%lf%lf", &c.x, &c.y ) != EOF ){ scanf( "%d", &n ); for( int i = 0; i < n; ++i ){ scanf( "%lf%lf", &p[i].x, &p[i].y ); p[i] = p[i] - c, p[i].ang = atan2( p[i].y, p[i].x ); } p[n] = p[0]; all = 0; for( int i = 0, k = 0; i < n; ++i ){ double d = fabs( p[i+1].ang - p[i].ang ); if( d < Pi ) add( p[i], p[i+1], k++ ); else{ point tmp = get_intersection( p[i], p[i+1], o, point( -1.0, 0 ) ); tmp.ang = Pi * dcmp( p[i].ang ); add( p[i], tmp, k++ ); tmp.ang = Pi * dcmp( p[i+1].ang ); add( tmp, p[i+1], k++ ); } } sort( L, L + all, cmp ); solve(); } return 0;}
0 0
- URAL 1464 Light
- Light
- URAL
- 【ural】
- URAL
- URAL
- URAL
- URAL
- URAL
- URAL
- URAL
- URAL
- URAL
- URAL
- URAL
- URAL
- URAL
- URAL
- Add and Search Word - Data structure design
- Intent 应用
- java gbk转utf-8乱码问题
- linux内置浏览器中文乱码
- iOS之APP保留更新接口被拒
- URAL 1464 Light
- HTML5之智能表单
- Java--截取路径字符串
- 高效率的YUV转RGB的OnPaint操作
- 两个栈实现一个队列
- HDU-4445 Crazy Tank
- 1002. The stack class
- Windows笔记本上开启Wi-Fi
- "std::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >::str() const"问题的解决办法