首页 > 代码库 > lightoj 1358

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;}

 

lightoj 1358