#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std; struct Point
{
double x;
double y;
} p[], px[];
int n;
double eps=1e-; 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)==)
{
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<&&d3*d4<)
return true;
else if(d1==&&on_segment(p3,p4,p1))
return true;
else if(d2==&&on_segment(p3,p4,p2))
return true;
else if(d3==&&on_segment(p1,p2,p3))
return true;
else if(d4==&&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=;
int count=;
for(i=; i<n; i++)
{
c = p[i];
d = p[i + ];
if(on_segment(c,d,a))//该点在多边形的一条边上
return ;
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%;//当L和多边形的交点数目C是奇数的时候,P在多边形内,是偶数的话P在多边形外。
} bool Intersect(Point s,Point e,Point a,Point b)
{
return direction(e,a,s)*direction(e,b,s)<=;
}//所在直线相交 double calculate(Point s,Point e)
{
int i,j,k=;
double sum;
Point a,b,temp;
for(i=; i<n; i++) //遍历所有点计算交点
{
a=p[i];
b=p[i+];
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==)
return 0.0;
sort(px,px+k,cmp); // 排序,由于割线是直线,所以交点必定线性分布
px[k]=px[];
sum=;
for(i=; i<k-; i++)
{
a=px[i];
b=px[i+];
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==)
break;
for(i=; i<n; i++)
scanf("%lf%lf",&p[i].x,&p[i].y);
p[n]=p[];
scanf("%lf%lf%lf%lf",&s.x,&s.y,&e.x,&e.y);
sum=calculate(s,e);
printf("%.3f\n",sum);
}
return ;
}

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

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

    搬砖 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Submissi ...

  2. 计算机学院大学生程序设计竞赛(2015’11)1005 ACM组队安排

    1005 ACM组队安排 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Pro ...

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

    Study Words Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

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

    Polygon Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Su ...

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

    The Country List Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

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

    #include<cstdio> #include<cstring> #include<map> #include<string> #include&l ...

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

    #include<cmath> #include<cstdio> #include<cstring> #include<algorithm> using ...

  8. 计算机学院大学生程序设计竞赛(2015’12) 1006 01 Matrix

    #include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> ...

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

    #include<cstdio> #include<algorithm> using namespace std; using namespace std; +; int a[ ...

随机推荐

  1. php5.6之后的版本使用curl以@+文件名的方式上传文件无效的解决版本

    使用curl上传文件使用file=@文件路径的方式,在php5.6以后的版本中无法使用了 官方文档给出明确解释 如果需要支持的话,可以将CURLOPT_SAFE_UPLOAD设置为false 或者使用 ...

  2. 使用queryperf对DNS服务器作压力测试

    一.querperf简介 当我们把DNS服务器配置好后,我们肯定会想测试一下DNS服务器的性能如何,上线后如果请求数够多服务器还能否响应?于是,我们可以使用软件模拟环境,对DNS服务器作评估性的测试. ...

  3. C++设计模式-Visitor访问者模式

    #include <iostream> #include <string> #include <string.h> #include <memory> ...

  4. php UNIX时间戳转换为指定日期格式

    用函数: date() 一般形式:date('Y-m-d H:i:s', unix时间) $date_unix=time();//获取当前时间,unix时间戳 echo 'Unix时间:'.$date ...

  5. LA2965 n个数中选出最多个数异或和为0

    intput n 1<=n<=24 n串只有大写字母的字符串 output 选出最多个字符串且每个大写字母出现的次数为偶数 第一行输出个数x 第二行输出x个字符串的下标 做法:将每个字符串 ...

  6. static方法与非static方法是否可以互相调用

    情况一.static方法调用非static方法 非静态方法只有实例对象才可调用,而静态方法随着类的加载而加载,类的加载在实例对象产生之前,所以静态方法不能调用非静态方法 情况二.非atic方法调用st ...

  7. js管理内存

    数据不再有用时,最好通过将其值置NULL来释放其引用-这个做法叫做解除引用(dereference).这个做法适用于全局变法和全局对象的属性. function createPerson(name){ ...

  8. AI 人工智能 探索 (十)

    呼叫事件图形结构如下 蓝色代表 警察局 红色代表警察 黄色代表 死亡人 蓝色球代表呼救人 黑色代表 敌人 警察目标是 攻击 黑色人,但 路中 会碰到 黄色人,如果警察有 救人功能 则会先救人去医院再看 ...

  9. AI 人工智能 探索 (四)

    在写之前,先对昨天寻路插件再做一些补充,因为该插件不是很完善,所以当我发现有不能满足需求的时候,就会试图更改源代码,或增加接口来符合我的需求. 昨天补充了一条是 自身转向代码,今天补充另外一条,是及时 ...

  10. CSS的命名

    使用约定俗称的命名规范有助于我们的代码阅读和维护. 常用命名: wrap  外套       ———————— 用于最外层 container 容器  ————————  和外套相似,用于做容器 he ...