HDU4404 Worms
来源:互联网 发布:老电视能看网络电视吗 编辑:程序博客网 时间:2024/05/21 11:30
http://acm.hdu.edu.cn/showproblem.php?pid=4404
2012jinhua online
求圆与多边形相交的面积。
模板题。
#include <cstdio>#include <cstring>#include <cmath>#include <map>#include <set>//#include <vector>#include <iostream>#include <algorithm>#include<string>using namespace std;//const double eps=1e-7;//const double INF=1e50;//const double pi=acos(-1);const int maxn = 105;#define pi acos(-1.0)struct point1{ double x, y ; point1(){} point1(double x, double y):x(x),y(y){} double operator *(const point1 &b)const{ return x * b.y - y * b.x; } point1 operator -(const point1 &b)const{ return point1( x - b.x, y - b.y ); } void in(){ scanf("%lf%lf",&x,&y); }}p[maxn] , q[maxn], o;const double eps = 1e-10;inline double max (double a, double b) { if (a > b) return a; else return b; }inline double min (double a, double b) { if (a < b) return a; else return b; }inline int fi (double a){ if (a > eps) return 1; else if (a >= -eps) return 0; else return -1;}class vector{public: double x, y; vector (void) {} vector (double x0, double y0) : x(x0), y(y0) {} double operator * (const vector& a) const { return x * a.y - y * a.x; } double operator % (const vector& a) const { return x * a.x + y * a.y; } vector verti (void) const { return vector(-y, x); } double length (void) const { return sqrt(x * x + y * y); } vector adjust (double len) { double ol = len / length(); return vector(x * ol, y * ol); } vector oppose (void) { return vector(-x, -y); }};class point{public: double x, y; point (void) {} point (double x0, double y0) : x(x0), y(y0) {} vector operator - (const point& a) const { return vector(x - a.x, y - a.y); } point operator + (const vector& a) const { return point(x + a.x, y + a.y); }};class segment{public: point a, b; segment (void) {} segment (point a0, point b0) : a(a0), b(b0) {} point intersect (const segment& s) const { vector v1 = s.a - a, v2 = s.b - a, v3 = s.b - b, v4 = s.a - b; double s1 = v1 * v2, s2 = v3 * v4; double se = s1 + s2; s1 /= se, s2 /= se; return point(a.x * s2 + b.x * s1, a.y * s2 + b.y * s1); } point pverti (const point& p) const { vector t = (b - a).verti(); segment uv(p, p + t); return intersect(uv); } bool on_segment (const point& p) const { if (fi(min(a.x, b.x) - p.x) <= 0 && fi(p.x - max(a.x, b.x)) <= 0 && fi(min(a.y, b.y) - p.y) <= 0 && fi(p.y - max(a.y, b.y)) <= 0) return true; else return false; }};double radius;point polygon[550];double kuras_area (point a, point b){ point ori(0, 0); int sgn = fi((b - ori) * (a - ori)); double da = (a - ori).length(), db = (b - ori).length(); int ra = fi(da - radius), rb = fi(db - radius); double angle = acos(((b - ori) % (a - ori)) / (da * db)); segment t(a, b); point h, u; vector seg; double ans, dlt, mov, tangle; if (fi(da) == 0 || fi(db) == 0) return 0; else if (sgn == 0) return 0; else if (ra <= 0 && rb <= 0) return fabs((b - ori) * (a - ori)) / 2 * sgn; else if (ra >= 0 && rb >= 0) { h = t.pverti(ori); dlt = (h - ori).length(); if (!t.on_segment(h) || fi(dlt - radius) >= 0) return radius * radius * (angle / 2) * sgn; else { ans = radius * radius * (angle / 2); tangle = acos(dlt / radius); ans -= radius * radius * tangle; ans += radius * sin(tangle) * dlt; return ans * sgn; } } else { h = t.pverti(ori); dlt = (h - ori).length(); seg = b - a; mov = sqrt(radius * radius - dlt * dlt); seg = seg.adjust(mov); if (t.on_segment(h + seg)) u = h + seg; else u = h + seg.oppose(); if (ra == 1) swap(a, b); ans = fabs((a - ori) * (u - ori)) / 2; tangle = acos(((u - ori) % (b - ori)) / ((u - ori).length() * (b - ori).length())); ans += radius * radius * (tangle / 2); return ans * sgn; }}int main(){ //freopen("a","r",stdin); int n, i; double v0,thi,time1,g,r; while(1) { scanf("%lf%lf%lf%lf%lf%lf%lf",&o.x,&o.y,&v0,&thi,&time1,&g,&radius); if (fabs(o.x)<eps && fabs(o.y)<eps && fabs(v0)<eps && fabs(thi)<eps && fabs(time1)<eps && fabs(g)<eps && fabs(radius)<eps) break; thi=thi*acos(-1)/180.00; o.x += v0*cos(thi)*time1 , o.y += v0*sin(thi)*time1-0.5*g*time1*time1 ; // cout<<o.x<<' '<<o.y<<' '<<r<<endl; double x,y; scanf("%d",&n); for (i = 0; i < n; i++) { scanf("%lf %lf", &x, &y); x-=o.x; y-=o.y; polygon[i] = point(x, y); } double area = 0; for (int i = 0; i < n; i++) area += kuras_area(polygon[i], polygon[(i + 1) % n]); printf("%.2f\n", fabs(area)); } return 0;}
#include <cstdio>#include <cstring>#include <cmath>#include <map>#include <set>//#include <vector>#include <iostream>#include <algorithm>#include<string>using namespace std;//const double eps=1e-7;//const double INF=1e50;//const double pi=acos(-1);const int maxn = 105;#define pi acos(-1.0)#define eps 1e-7// poj 3675 一个圆和一个多边形的面积交的大double sign( double x ){ if( x < -eps ) return -1; return x > eps;}struct point{ double x, y ; point(){} point(double x, double y):x(x),y(y){} double operator *(const point &b)const{ return x * b.y - y * b.x; } point operator -(const point &b)const{ return point( x - b.x, y - b.y ); } void in(){ scanf("%lf%lf",&x,&y); }}p[maxn] , q[maxn], o,p0;double r ,ans ; // 已原点为圆心的圆半径double thi,time1,g,v0;////圆o与线段x-y的交点,,如果存在顺序存入p[0]和p[1],,返回交点的个数int xianduan_jiao_yuan( point o, double r,point u, point v, point &o1, point &o2){ u = u - o; v = v - o; point w = v - u ; double a = w.x * w.x + w.y * w.y ; double b = w.x * u.x * 2 + w.y * u.y * 2; double c = u.x * u.x + u.y * u.y - r * r; double d = b * b - 4 * a * c; if( sign( d ) < 0) return 0; d = sqrt( d ); double t1 = ( - b + d )/2/a, t2 = ( - b - d )/2/a; if( t1 > t2 ) swap( t1, t2 ); int ans = 0; ////注意这里端点在圆上没有算作相交,有需要改成等号既可 if( sign( t1 ) > 0 && sign( t1 - 1 ) < 0 ){ ans ++ ; o1 = point( u.x + w.x * t1 + o.x, u.y + w.y*t1+o.y); }////注意重根这里算作了一个交点,, if(sign( t1 - t2) != 0 && sign(t2)>0&&sign(t2-1)<0){ ans ++; if( ans == 1 ) o1 = point( u.x+w.x*t2+o.x,u.y+w.y*t2+o.y ); else o2 = point( u.x+w.x*t2+o.x,u.y+w.y*t2+o.y ); } return ans ;}double get( point p[], int n ){ double ans = 0; for( int i = 1; i < n; i ++ ){ point a, b; a = p[ i - 1]; b = p[ i ];//只要有一个人在圆外面 那就只需要计算扇形的面积即可 if( sqrt(a.x*a.x+a.y*a.y) - r > eps || sqrt( b.x * b.x + b.y*b.y) - r > eps ){ double t = atan2(b.y , b.x ) - atan2(a.y , a.x ) ; while( t - pi > eps ) t -= pi * 2 ;//t的范围是( -pi , pi ) while( t + pi < -eps ) t += pi * 2 ; ans += t * r * r ; }else ans += a * b ; //叉乘 这个在圆里面 } return ans ;}void add( point a , point b ){ point p1, p2; int end = 0; p[end++] = a; point o1, o2; int t = xianduan_jiao_yuan(point(0,0),r,a,b,o1,o2); if( t >= 1) p[end++] = o1; if( t >= 2) p[end++] = o2; p[end++] = b; ans += get( p, end );}int main(){ //freopen("a","r",stdin); int n, i; double v0,thi,time1,g; while(1) { scanf("%lf%lf%lf%lf%lf%lf%lf",&o.x,&o.y,&v0,&thi,&time1,&g,&r); if (fabs(o.x)<eps && fabs(o.y)<eps && fabs(v0)<eps && fabs(thi)<eps && fabs(time1)<eps && fabs(g)<eps && fabs(r)<eps) break; thi=thi*acos(-1)/180.00; o.x += v0*cos(thi)*time1 , o.y += v0*sin(thi)*time1-0.5*g*time1*time1 ; ans=0; scanf("%d",&n); for( i = 0; i < n; i ++ ){ scanf("%lf%lf",&q[i].x, &q[i].y ); q[i] = q[i] - o; } q[n] = q[0]; for( i =0; i < n; i++ ){ add( q[i], q[i+1] ); } printf("%.2lf\n",fabs(ans)/2); } return 0;}
- HDU4404 Worms
- HDU4404 Worms(计算多边形和圆的重叠面积)
- Worms
- B. Worms
- B. Worms
- Google Search API Worms
- <cf>Worms Evolution
- hdu 4404 Worms
- Worms(水题)
- [Codeforces] 474B - Worms
- CodeForces 474B(Worms)
- 【CODEFORCES】 B. Worms
- CF 474B Worms
- A. Worms Evolution
- hdu 4404 worms #by nobody
- CodeForces 474B Worms 二分
- Why is OpenVMS Secure? Worms? Viruses?
- Ubuntu下wine玩Worms World Party
- epoll的使用
- 【学习STM32F4】第五天
- 打印素数
- MYSQL ERROR 1045 错误的解决办法
- C++ 虚函数表解析
- HDU4404 Worms
- java jdk1.6内置支持的webservice使用示例
- 异或 算法 小总结
- 【服务器】基于jabber(XMPP)架设内部即时通讯服务
- Android 软键盘按键监控
- Java学习(回顾)笔记之day3
- pkgm : 动态压缩包维护与安装脚本
- HDU4405 Aeroplane chess
- Java学习(回顾)笔记之day4