计算机学院大学生程序设计竞赛(2015’12) 1002 Polygon

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;

struct Point
{
    double x;
    double y;
} p[1001], px[10001];
int n;
double eps=1e-8;

int cmp(Point a, Point b)
{
    if(abs(a.x-b.x)<eps)
        return a.y<b.y;
    return a.x<b.x;
}

double dist(Point a,Point b)//求距离
{
    return sqrt((a.x - b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}

double direction(Point pi,Point pj,Point pk)
{
    return (pk.x-pi.x)*(pj.y-pi.y)-(pj.x-pi.x)*(pk.y-pi.y);
}

bool on_segment(Point pi,Point pj,Point pk)//判断点pk时候在线段pi, pj上
{
    if(direction(pi, pj, pk)==0)
    {
        if(pk.x>=min(pi.x,pj.x)&&pk.x<=max(pi.x,pj.x)&&pk.y>=min(pi.y,pj.y)&&pk.y<=max(pi.y,pj.y))
            return true;
    }
    return false;
}

bool segments_intersect(Point p1,Point p2,Point p3,Point p4)//判断线段是否相交
{
    double d1=direction(p3,p4,p1);
    double d2=direction(p3,p4,p2);
    double d3=direction(p1,p2,p3);
    double d4=direction(p1,p2,p4);
    if(d1*d2<0&&d3*d4<0)
        return true;
    else if(d1==0&&on_segment(p3,p4,p1))
        return true;
    else if(d2==0&&on_segment(p3,p4,p2))
        return true;
    else if(d3==0&&on_segment(p1,p2,p3))
        return true;
    else if(d4==0&&on_segment(p1,p2,p4))
        return true;
    return false;
}

Point intersection(Point a1, Point a2, Point b1, Point b2)//计算线段交点
{
    Point ret = a1;
    double t = ((a1.x - b1.x) * (b1.y - b2.y) - (a1.y - b1.y) * (b1.x - b2.x))
               / ((a1.x - a2.x) * (b1.y - b2.y) - (a1.y - a2.y) * (b1.x - b2.x));
    ret.x += (a2.x - a1.x) * t;
    ret.y += (a2.y - a1.y) * t;
    return ret;
}

int InPolygon(Point a)//判断点是否在多边形的内部
{
    int i;
    Point b,c,d;
    b.y=a.y;
    b.x=1e15;//定义射线
    int flag=0;
    int count=0;
    for(i=0; i<n; i++)
    {
        c = p[i];
        d = p[i + 1];
        if(on_segment(c,d,a))//该点在多边形的一条边上
            return 1;
        if(abs(c.y-d.y)<eps)
            continue;
        if(on_segment(a,b,c))//和顶点相交的情况,如果y值较大则取
        {
            if(c.y>d.y)
                count++;
        }
        else if(on_segment(a,b,d))//和顶点相交的情况,如果y值较大则取
        {
            if(d.y>c.y)
                count++;
        }
        else if(segments_intersect(a,b,c,d))//和边相交
            count++;
    }
    return count%2;//当L和多边形的交点数目C是奇数的时候,P在多边形内,是偶数的话P在多边形外。
}

bool Intersect(Point s,Point e,Point a,Point b)
{
    return direction(e,a,s)*direction(e,b,s)<=0;
}//所在直线相交

double calculate(Point s,Point e)
{
    int i,j,k=0;
    double sum;
    Point a,b,temp;
    for(i=0; i<n; i++) //遍历所有点计算交点
    {
        a=p[i];
        b=p[i+1];
        if(abs(direction(e,a,s))<eps&&abs(direction(e,b,s))<eps)
        {
            px[k++]=a;
            px[k++]=b;
        }
        else if(Intersect(s,e,a,b))//两直线相交
        {
            px[k++]=intersection(s,e,a,b);//两直线交点
        }
    }
    if(k==0)
        return 0.0;
    sort(px,px+k,cmp); // 排序,由于割线是直线,所以交点必定线性分布
    px[k]=px[0];
    sum=0;
    for(i=0; i<k-1; i++)
    {
        a=px[i];
        b=px[i+1];
        temp.x=(a.x+b.x)/2.0;
        temp.y=(a.y+b.y)/2.0;
        if(InPolygon(temp))//如果两点的中点在多边形外部,说明直线在外部
            sum+=dist(a,b);
    }
    return sum;
}

int main()
{
    int q,i,j;
    double sum;
    Point s,e;
    while(~scanf("%d",&n))
    {
        if(n==0)
            break;
        for(i=0; i<n; i++)
            scanf("%lf%lf",&p[i].x,&p[i].y);
        p[n]=p[0];
            scanf("%lf%lf%lf%lf",&s.x,&s.y,&e.x,&e.y);
            sum=calculate(s,e);
            printf("%.3f\n",sum);
    }
    return 0;
}
时间: 2024-08-01 19:16:36

计算机学院大学生程序设计竞赛(2015’12) 1002 Polygon的相关文章

hdu 计算机学院大学生程序设计竞赛(2015’11)

搬砖 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Submission(s): 5134    Accepted Submission(s): 1288 Problem Description 小明现在是人见人爱,花见花开的高富帅,整天沉浸在美女环绕的笙歌妙舞当中.但是人们有所不知,春风得意的小明也曾有着一段艰苦的奋斗史. 那时的小明还没剪去长发,没有信用卡没有她

HDU计算机学院大学生程序设计竞赛(2015’12)Happy Value

Happy Value Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1453    Accepted Submission(s): 428 Problem Description In an apartment, there are N residents. The Internet Service Provider (ISP) wa

HDU计算机学院大学生程序设计竞赛(2015’12)The Country List

The Country List Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2598    Accepted Submission(s): 615 Problem Description As the 2010 World Expo hosted by Shanghai is coming, CC is very honorable

计算机学院大学生程序设计竞赛(2015’12)The collector’s puzzle

Problem Description There is a collector who own many valuable jewels. He has a problem about how to store them. There are M special boxes. Each box has a value. And each of the N jewels has a value too. The collector wants to store every jewel in on

计算机学院大学生程序设计竞赛(2015’12) 1003 The collector’s puzzle

#include<cstdio> #include<algorithm> using namespace std; using namespace std; const int maxn=100000+10; int a[maxn],b[maxn]; int main() { int n,m; while(scanf("%d %d",&n,&m)!=EOF) { for(int i=1; i<=n; i++) scanf("%d&

计算机学院大学生程序设计竞赛(2015’12) 1001 The Country List

#include<cstdio> #include<cstring> #include<cmath> #include<string> #include<vector> #include<map> #include<algorithm> using namespace std; char s[100+10][20+10]; int n; map<string ,int>m; int main() { while

计算机学院大学生程序设计竞赛(2015’12) 1005 Bitwise Equations

#include<cmath> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=120; long long X,K; long long basex[maxn]; long long basek[maxn]; int totx,totk; int main() { int T; scanf("%d",&a

计算机学院大学生程序设计竞赛(2015’12) 1008 Study Words

#include<cstdio> #include<cstring> #include<map> #include<string> #include<algorithm> using namespace std; int T; char s[100+10]; char r[100+10]; map<string,int>m; struct dan { char s[100+10]; int num; }d[1000000+10]; i

计算机学院大学生程序设计竞赛(2015’12) 1009 The Magic Tower

#include<cmath> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int whp,wat,wdef,bhp,bat,bdef; char s; int main() { while(~scanf("%c",&s)) { scanf("%d%d%d",&whp,&wat,&