计算机学院大学生程序设计竞赛(2015’12) 1002 Polygon
#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的更多相关文章
- hdu 计算机学院大学生程序设计竞赛(2015’11)
搬砖 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)Total Submissi ...
- 计算机学院大学生程序设计竞赛(2015’11)1005 ACM组队安排
1005 ACM组队安排 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Pro ...
- 计算机学院大学生程序设计竞赛(2015’12)Study Words
Study Words Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tota ...
- 计算机学院大学生程序设计竞赛(2015’12)Polygon
Polygon Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Su ...
- 计算机学院大学生程序设计竞赛(2015’12)The Country List
The Country List Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- 计算机学院大学生程序设计竞赛(2015’12) 1008 Study Words
#include<cstdio> #include<cstring> #include<map> #include<string> #include&l ...
- 计算机学院大学生程序设计竞赛(2015’12) 1009 The Magic Tower
#include<cmath> #include<cstdio> #include<cstring> #include<algorithm> using ...
- 计算机学院大学生程序设计竞赛(2015’12) 1006 01 Matrix
#include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> ...
- 计算机学院大学生程序设计竞赛(2015’12) 1003 The collector’s puzzle
#include<cstdio> #include<algorithm> using namespace std; using namespace std; +; int a[ ...
随机推荐
- javascript克隆一个对象
/* * 克隆一个对象 */ com.ty.repairtech.JsonOperation.clone = function(obj) { // Handle the 3 simple types, ...
- PHP fpm优化【转】
在优化PHP的进程数的时候我们首先要了解我们服务器执行一个php使用的内存 1: 查询一个php占用的内存方法 pmap $(pgrep php-fpm | head -1) 我这里查询到的是 000 ...
- isPostBack原理
从 到输入用户名,点击提交按钮 这个过程就叫做postback(是两个不同的状态) 利用ispostback原理,实现是否第一次进入处理程序(上一个用用户名判断的不好,会导致在用户名空的情况下 ...
- Bitmap和Drawable浅谈
一.概念区别 Bitmap - 称作位图,一般位图的文件格式后缀为bmp,当然编码器也有很多如RGB565.RGB8888.作为一种逐像素的显示对象执行效率高,但是缺点也很明显存储效率低.我们理解为一 ...
- Inno Setup入门(十五)——Inno Setup类参考(1)
分类: Install Setup 2013-02-02 11:27 536人阅读 评论(0) 收藏 举报 nno setup脚本能够支持许多的类,这些类使得安装程序的功能得到很大的加强,通过对这些类 ...
- 将undefault和null的数据转换成bool类型的数据 使用!!
<script> var o={}; var a=null; console.info(!!o.name); </script> 输出false 此方法是将undefault和 ...
- java中怎么解决路径中文的问题
在我遇到精灵线程的问题时,遇到一个中文路径的问题 原来是这样的 URL url=Test8.class.getClassLoader().getResource(""); Stri ...
- ignite客户端找不到服务端的时候如何设置退出
ignite启动客户端时需要有服务端支持: Ignition.setClientMode(true); Ignition.start("ignite.xml"); 这里有个问题,当 ...
- 【转】从1到N这N个数中1的出现了多少次?
给定一个十进制整数N,求出从1到N的所有整数中出现"1"的个数. 例如:N=2,1,2出现了1个"1". N=12,1,2,3,4,5,6,7,8,9,10,1 ...
- Net Protocol Related
Data used to deliver through net should be encapsulated. General encapsulation include 4 layer of he ...