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;
}
时间: 2024-09-28 17:31:48

lightoj 1358的相关文章

LightOJ 1030 Discovering Gold【概率】

题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1030 题意:基础概率题. 代码: #include <stdio.h> #include <string.h> #include <vector> #include <string> #include <algorithm> #include <iostream> #include <iterator>

LightOJ - 1370 Bi-shoe and Phi-shoe

题目链接:http://lightoj.com/login_main.php?url=volume_showproblem.php?problem=1370 题目大意:给N个数a[i], N <= 1e6,问使 Φ(x) >= a[i] 成立的最小x的所有x的和是多少. 解题思路:我们知道的是对于素数 m 来说,phi[m] = m - 1.另一方面,对于一个合数 m 来说, phi[m] < phi[x] , x > m && x 是素数. 因此,我们可以认为,每

lightoj 1057 - Collecting Gold(状压dp)

题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1057 题解:看似有点下记忆话搜索但是由于他是能走8个方向的也就是说两点的距离其实就是最大的x轴或y轴的差.然后只有15个藏金点状压一下加dfs就行了. #include <iostream> #include <cstring> #include <cstdio> #include <cmath> #define inf 0X3f3f3f

Lightoj 1088 - Points in Segments 【二分】

题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1088 题意: 有一维的n个点和q条线段.询问每条线段上的点有多少个: 思路:寻找这些点中对于每条线段的上下界即可. 代码: #include <stdio.h> #include <ctime> #include <math.h> #include <limits.h> #include <complex> #include

Lightoj 1090 - Trailing Zeroes (II)

题目连接: http://www.lightoj.com/volume_showproblem.php?problem=1090 题目大意: 给出n,r,p,q四个数字1<=n,r,p,q<=1000000,求出的末尾有几个0? 解题思路: 是不是一下子懵了,数字好大,复杂度好高,精度怎么办···············,就问你怕不怕? 因为你是Acmer,这都不应该是问题.因为10的因子只有2和5,所以可以打表保存从1到当前数字相乘的积中分别含有2,5的个数.然后算出中分别含有2,5的个数,

暑期训练狂刷系列——Lightoj 1084 - Winter bfs

题目连接: http://www.lightoj.com/volume_showproblem.php?problem=1084 题目大意: 有n个点在一条以零为起点的坐标轴上,每个点最多可以移动k,问最终能不能把所有点都聚集在大于等于三个点的集合里面,如果能最少需要几个这样的集合? 解题思路: 刚开始看到题目感觉好简单,就开始了sort然后贪心之旅,这就是错误的开始.最后发现这样并不行,然后再Alex的提醒下想用单调队列优化,在我愚昧的理解下竟然写成了bfs,提交竟然ac了,surprise~

LightOJ - 1148 - Mad Counting

先上题目: 1148 - Mad Counting   PDF (English) Statistics Forum Time Limit: 0.5 second(s) Memory Limit: 32 MB Mob was hijacked by the mayor of the Town "TruthTown". Mayor wants Mob to count the total population of the town. Now the naive approach to

LightOJ 1013 LCS+记忆化搜索

http://www.lightoj.com/volume_showproblem.php?problem=1013 题目大意: 给两个字符串,问最短的满足子串包含给的两个字符串的字符串的最短长度,以及最短长度的字符串的个数. 第一个问题就是简单的LCS,两个串长度和减去公共部分. 第二个问题要进行记忆话搜索来查找.dp(i,j,l)(第一个串i位,第二个串j位,总串l位) 转移方程 dp(i,j,l) = dp(i-1,j-1,l-1) (s1[i] = s2[j]时) dp(i,j,l) =

1358 棋盘游戏[状压dp]

1358 棋盘游戏 时间限制: 1 s 空间限制: 64000 KB 题目等级 : 大师 Master 题解 查看运行结果 题目描述 Description 这个游戏在一个有10*10个格子的棋盘上进行,初始时棋子位于左上角,终点为右下角,棋盘上每个格子内有一个0到9的数字,每次棋子可以往右方或下方的相邻格子移动,求一条经过数字之和最小且经过0到9的所有数字的合法路径,输出其长度.(经过的数字包括左上角和右下角) 输入描述 Input Description 输入包含10行,每行10个数字,以空