lightoj 1358

问圆和多边形相交,什么时候比例可以是一个定值。

二分加模板,可就是过不了。。。伤心。。。帖一发新模板,意思都一样,真是纠结了。

http://tokers.cn/2015/10/08/lightoj1358-fukushima-nuclear-blast%e4%ba%8c%e5%88%86%e5%9c%86%e5%92%8c%e5%a4%9a%e8%be%b9%e5%bd%a2%e6%b1%82%e4%ba%a4/

#include <iostream>
#include <fstream>
#include <cstring>
#include <climits>
#include <deque>
#include <cmath>
#include <queue>
#include <stack>
#include <ctime>
#include <list>
#include <map>
#include <set>
#include <utility>
#include <sstream>
#include <complex>
#include <string>
#include <vector>
#include <cstdio>
#include <bitset>
#include <functional>
#include <algorithm>
 
using namespace std;
 
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
const double eps = 1e-8;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair <int, int> PLL;
const LL INF = (1LL << 60);
 
const int N = 5010;
 
int sgn(double x) {
    if (fabs(x) < eps) {
        return 0;
    }
    if (x < 0) {
        return -1;
    }
    return 1;
}
 
struct Point {
    double x, y;
    Point() {};
    Point(double _x, double _y) {
        x = _x;
        y = _y;
    }
    void input() {
        scanf("%lf%lf", &x, &y);
    }
 
    double operator ^ (const Point &b) const {
        return x * b.y - y * b.x;
    }
 
    bool operator == (Point b) const {
        return sgn(x - b.x) == 0 && sgn(y - b.y) == 0;
    }
 
    bool operator < (Point b) const {
        return sgn(x - b.x) == 0 ? sgn(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 / (const double &k) const {
        return Point(x / k, y / k);
    }
 
    double operator * (const Point &b) const {
        return x * b.x + y * b.y;
    }
 
    double distance(Point p) {
        return hypot(x - p.x, y - p.y);
    }
    
    double len() {
        return hypot(x, y);
    }
 
    double len2() {
        return x * x + y * y;
    }
 
    double rad(Point a, Point b) {
        Point p = *this;
        return fabs(atan2( fabs((a - p) ^ (b - p)), (a - p) * (b - p) ));
    }
    
    Point operator * (const double &k) const {
        return Point(x * k, y * k);
    }
 
    Point trunc(double r) {
        double l = len();
        if (!sgn(l)) {
            return *this;
        }
        r /= l;
        return Point(x * r, y * r);
    }
}; 
 
struct Line {
    Point s, e;
    Line(Point _s, Point _e) {
        s = _s;
        e = _e;
    }
 
    double length() {
        return s.distance(e);
    }
 
    double dispointtoline(Point p) {
        return fabs((p - s) ^ (e - s)) / length();
    }
 
    Point lineprog(Point p) {
        return s + ( ((e - s) * ((e - s) * (p - s))) / ((e - s).len2()) );
    }
};
 
struct Circle {
    Point p;
    double r;
    Circle() {}
 
    Circle(Point _p, double _r) {
        p = _p;
        r = _r;
    }
    
    int pointcrossline(Line v, Point &p1, Point &p2) {
        if (!(*this).relationline(v)) {
            return 0;
        }
        Point a = v.lineprog(p);
        double d = v.dispointtoline(p);
        d = sqrt(r * r - d * d);
        if (sgn(d) == 0) {
            p1 = a;
            p2 = a;
            return 1;
        }
        p1 = a + (v.e - v.s).trunc(d);
        p2 = a - (v.e - v.s).trunc(d);
        return 2;
    }
 
    int relation(Point b) {
        double dst = b.distance(p);
        if (sgn(dst - r) < 0) {
            return 2;
        }
        else if (sgn(dst - r) == 0) {
            return 1;
        }
        return 0;
    }
 
    int relationline(Line v) {
        double dst = v.dispointtoline(p);
        if (sgn(dst - r) < 0) {
            return 2;
        }
        else if (sgn(dst - r) == 0) {
            return 1;
        }
        return 0;
    }
 
    double areatriangle(Point a, Point b) {
        if (sgn((p - a) ^ (p - b)) == 0) {
            return 0.0;
        }
        Point q[5];
        int len = 0;
        q[len++] = a;
        Line l(a, b);
        Point p1, p2;
        if (pointcrossline(l, q[1], q[2]) == 2) {
            if (sgn( (a - q[1]) * (b - q[1]) ) < 0) {
                q[len++] = q[1];
            }
            if (sgn( (a - q[2]) * (b - q[2]) ) < 0) {
                q[len++] = q[2];
            }
        }
        q[len++] = b;
        if (len == 4 && sgn( (q[0] - q[1]) * (q[2] - q[1]) ) > 0) {
            swap(q[1], q[2]);
        }
        double res = 0;
        for (int i = 0; i < len - 1; ++i) {
            if (relation(q[i]) == 0 || relation(q[i + 1]) == 0) {
                double arg = p.rad(q[i], q[i + 1]);
                res += r * r * arg / 2.0;
            }
            else {
                res += fabs((q[i] - p) ^ (q[i + 1] - p)) / 2.0;
            }
        }
        return res;
    }
};
 
struct Polygon {
    int n;
    Point p[N];
 
    void input(int _n) {
        n = _n;
        for (int i = 0; i < n; ++i) {
            p[i].input();
        }
    }
 
    double areacircle(Circle c) {
        double ans = 0;
        for (int i = 0; i < n; ++i) {
            int j = (i + 1) % n;
            if (sgn( (p[j] - c.p) ^ (p[i] - c.p) ) >= 0) {
                ans += c.areatriangle(p[i], p[j]);
            }
            else {
                ans -= c.areatriangle(p[i], p[j]);
            }
        }
        return fabs(ans);
    }
 
    double getarea() {
        double sum = 0;
        for (int i = 0; i < n; ++i) {
            sum += (p[i] ^ p[(i + 1) % n]);
        }
        return fabs(sum) / 2;
    }
 
}pn;
 
int main() {
    int t, icase = 1;
    scanf("%d", &t);
    while (t--) {
        int n;
        scanf("%d", &n);
        pn.input(n);
        double x, y;
        int p;
        scanf("%lf%lf%d", &x, &y, &p);
        double sum = pn.getarea();
        double l = 0, r = 5000, mid;
        double ans = 0;
        while (r - l > eps) {
            mid = (l + r) / 2;
            Circle c(Point(x, y), mid);
            double area = pn.areacircle(c);
            if (area - sum * p * 0.01 < -eps) {
                l = mid;
            }
            else {
                ans = mid;
                r = mid;
            }
        }
        printf("Case %d: %.0f\n", icase++, ans);
    }
    return 0;
}

下面是我写的,也看不出来为什么错。

#include <cstdio>
#include <cstring>
#include <vector>
#include <cmath>
#include <stack>
#include <cstdlib>
#include <queue>
#include <map>
#include <iostream>
#include <algorithm>
#include <bits/stdc++.h>
#include <queue>
#include <ctime>

using namespace std;
const double Pi=acos(-1.0);
const double eps=1e-10;
struct point
{
    double x,y;
} a[5100];
double r;
double x_mul(point a,point b,point c)
{
    return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);
}
double dist_1point(double x0,double y0)
{
    return sqrt(x0*x0+y0*y0);
}
double dist_2point(double x1,double y1,double x2,double y2)
{
    return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
double dist_line(double x1,double y1,double x2,double y2)
{
    double A,B,C,dist;
    A=y1-y2;
    B=x1-x2;
    C=x1*y2-x2*y1;
    dist=fabs(C)/sqrt(A*A+B*B);
    return dist;
}
double get_cos(double a,double b,double c)
{
    double angel=(b*b+c*c-a*a)/(2*b*c);
    return angel;
}
point get_point(double x0,double y0)
{
    double k;
    point temp;
    if(x0!=0)
    {
        k=y0/x0;
        temp.x=fabs(r)/sqrt(1+k*k);
        if(x0<0) temp.x=-temp.x;
        temp.y=k*temp.x;
    }
    else
    {
        temp.x=0;
        if(y0>0) temp.y=r;
        else temp.y=-r;
    }
    return temp;
}
int fi(double x1,double y1,double x2,double y2)
{
    if (x1*y2-x2*y1>0) return 1;
    else return -1;
}

double get_area(double x1,double y1,double x2,double y2)
{
    int sign=fi(x1,y1,x2,y2);
    double s;
    double l=dist_line(x1,y1,x2,y2);
    double a=dist_1point(x1,y1);
    double b=dist_1point(x2,y2);
    double c=dist_2point(x1,y1,x2,y2);
    if(a==0 || b==0)
        return 0;


    if(a<=r && b<=r)
    {
        s=fabs(x1*y2-x2*y1)/2.0;
        return s*sign;
    }


    else if(a>=r && b>=r && l>=r)
    {
        point t1=get_point(x1,y1);
        point t2=get_point(x2,y2);
        double d=dist_2point(t1.x,t1.y,t2.x,t2.y);
        double sita1=acos(get_cos(d,r,r));
        double s=fabs(sita1*r*r/2.0);
        return s*sign;
    }


    else if(a>=r && b>=r && l<=r && (get_cos(a,b,c)<=0 || get_cos(b,a,c)<=0))
    {
        point t1=get_point(x1,y1);
        point t2=get_point(x2,y2);
        double d=dist_2point(t1.x,t1.y,t2.x,t2.y);
        double sita=acos(get_cos(d,r,r));
        s=fabs(sita*r*r/2.0);
        return s*sign;
    }


    else if(a>=r && b>=r && l<=r && (get_cos(a,b,c)>0 && get_cos(b,a,c)>0))
    {
        double xx1,xx2,yy1,yy2;
        if(x1!=x2)
        {
            double k12=(y1-y2)/(x1-x2);
            double b12=y1-k12*x1;
            double a0=(1+k12*k12);
            double b0=(2*k12*b12);
            double c0=(b12*b12-r*r);
            xx1=(-b0+sqrt(b0*b0-4*a0*c0))/(2*a0);
            yy1=k12*xx1+b12;
            xx2=(-b0-sqrt(b0*b0-4*a0*c0))/(2*a0);
            yy2=k12*xx2+b12;
        }
        else
        {
            xx1=x1;
            xx2=x1;
            yy1=sqrt(r*r-x1*x1);
            yy2=-sqrt(r*r-x1*x1);
        }
        point t1=get_point(x1,y1);
        point t2=get_point(x2,y2);
        double d1=dist_2point(xx1,yy1,xx2,yy2);
        double d2=dist_2point(t1.x,t1.y,t2.x,t2.y);
        double sita1=acos(get_cos(d1,r,r));
        double sita2=acos(get_cos(d2,r,r));
        double s1=fabs(sita1*r*r/2.0);
        double s2=fabs(sita2*r*r/2.0);
        double s3=fabs(xx1*yy2-xx2*yy1)/2.0;
        s=s2+s3-s1;
        return s*sign;
    }


    else if(a>=r && b<=r)
    {
        double xxx,yyy;
        if(x1!=x2)
        {
            double k12=(y1-y2)/(x1-x2);
            double b12=y1-k12*x1;
            double a0=(1+k12*k12);
            double b0=(2*k12*b12);
            double c0=(b12*b12-r*r);

            double xx1=(-b0+sqrt(b0*b0-4*a0*c0))/(2*a0);
            double yy1=k12*xx1+b12;
            double xx2=(-b0-sqrt(b0*b0-4*a0*c0))/(2*a0);
            double yy2=k12*xx2+b12;

            if(x1<=xx1 && xx1<=x2 || x2<=xx1 && xx1<=x1)
            {
                xxx=xx1;
                yyy=yy1;
            }
            else
            {
                xxx=xx2;
                yyy=yy2;
            }
        }
        else
        {
            double xx1=x1;
            double yy1=-sqrt(r*r-x1*x1);
            double yy2=sqrt(r*r-x1*x1);

            if(y1<=yy1 && yy1<=y2 || y2<=yy1 && yy1<=y1)
            {
                yyy=yy1;
                xxx=xx1;
            }
            else
            {
                yyy=yy2;
                xxx=xx1;
            }
        }
        point t1=get_point(x1,y1);
        double ddd=dist_2point(t1.x,t1.y,xxx,yyy);
        double sita1=acos(get_cos(ddd,r,r));
        double s1=fabs(sita1*r*r/2.0);
        double s3=fabs(xxx*y2-yyy*x2)/2.0;
        s=s1+s3;
        return s*sign;
    }
    else if(a<=r && b>=r)
    {
        double xxx,yyy;
        if(x1-x2!=0)
        {
            double k12=(y1-y2)/(x1-x2);
            double b12=y1-k12*x1;
            double a0=(1+k12*k12);
            double b0=(2*k12*b12);
            double c0=(b12*b12-r*r);
            double xx1=(-b0+sqrt(b0*b0-4*a0*c0))/(2*a0);
            double yy1=k12*xx1+b12;
            double xx2=(-b0-sqrt(b0*b0-4*a0*c0))/(2*a0);
            double yy2=k12*xx2+b12;
            if(x1<=xx1 && xx1<=x2 || x2<=xx1 && xx1<=x1)
            {
                xxx=xx1;
                yyy=yy1;
            }
            else
            {
                xxx=xx2;
                yyy=yy2;
            }
        }
        else
        {
            double yy1=-sqrt(r*r-x1*x1);
            double yy2=sqrt(r*r-x1*x1);
            double xx1=x1;
            if(y1<=yy1 && yy1<=y2 || y2<=yy1 && yy1<=y1)
            {
                yyy=yy1;
                xxx=xx1;
            }
            else
            {
                yyy=yy2;
                xxx=xx1;
            }
        }
        point t1=get_point(x2,y2);
        double ddd=dist_2point(t1.x,t1.y,xxx,yyy);
        double sita1=acos(get_cos(ddd,r,r));
        double s1=fabs(sita1*r*r/2.0);
        double s3=fabs(xxx*y1-yyy*x1)/2.0;
        s=s1+s3;
        return s*sign;
    }
    else return 0;
}

int main()
{
//    double area, x0, y0, v, angle, t, g;
//
//    int i,n;
//    while(scanf("%lf%lf%lf%lf%lf%lf%lf", &x0, &y0, &v, &angle, &t, &g, &r)!=EOF)
//    {
//        if(fabs(x0)+fabs(y0)+fabs(v)+fabs(angle)+fabs(t)+fabs(g)+
//                fabs(r)<0.0000001)break;
//        scanf("%d", &n);
//        for(i=0; i<n; i++)
//            scanf("%lf%lf", &a[i].x, &a[i].y);
//        area=0;
//
//
//        double xx,yy;
//        xx=x0+v*cos(angle/180.0*Pi)*t;
//        yy=y0+v*sin(angle/180.0*Pi)*t-0.5*g*t*t;
//        for(i=0; i<n; i++)//此模板精度高有很大一部分原因是把圆心定在原点
//            a[i].x-=xx,a[i].y-=yy;
//
//        //半径就是r
//        for(i=0; i<n; i++)
//        {
//            area+=get_area(a[i].x,a[i].y,a[(i+1)%n].x,a[(i+1)%n].y);
//        }
//        printf("%.2f\n",fabs(area));
//    }


    int T,ncas=1;
    scanf ("%d",&T);
    while (T--)
    {
        int n;
        scanf ("%d",&n);
        for (int i=0; i<n; i++)
        {
            scanf ("%lf%lf",&a[i].x,&a[i].y);
        }
        double stdarea=0;
        for (int i=0; i<n; i++)
        {
            stdarea+=x_mul(a[i],a[(i+1)%n],a[(i+2)%n])/2.0;
//            printf ("%f\n",x_mul(a[i],a[(i+1)%n],a[(i+2)%n])/2.0);
        }
        stdarea=abs(stdarea)/2.0;
//            printf ("%f\n",stdarea);
        if (n==3) stdarea=abs(x_mul(a[0],a[(1)%n],a[(2)%n])/2.0);
        double area=0;
        double xx,yy,rate;
        scanf ("%lf%lf%lf",&xx,&yy,&rate);
        double L=0,R=0x7f7f7f7f,ans;
        while ((R-L)>eps)
        {
            r=(L+R)/2.0;
            area=0;
            for (int i=0; i<n; i++)
            {
                area+=get_area(a[i].x-xx,a[i].y-yy,a[(i+1)%n].x-xx,a[(i+1)%n].y-yy);
            }
            area=abs(area);
            double temp=area*100.0;
            if (temp-rate*stdarea>=-eps)
            {
                ans=r;
                R=r;
            }
            else L=r;
        }
        printf ("Case %d: %.0f\n",ncas++,ans);
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/nj-czy/p/5867901.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值