2015 北京网络赛 E Border Length hihoCoder 1231 树状数组 (2015-11-05 09:30)
#1231 : Border Length
描述
Garlic-Counting Chicken is a special species living around the Lake of Peking University.
A Garlic-Counting Chicken always flies out from home in the morning, goes to some fixed points looking for buuugs(a kind of worm), and comes back home in the afternoon.
Students from the School of Life Sciences find that, a Garlic-Counting Chicken always flies a straight line between two points, and its trace never goes across itself. The students want to find out the relationship between Garlic-Counting Chicken and the Lake. So they ask you to calculate the length of border of the common area between the Lake and one Garlic-Counting Chicken's daily trace.
输入
There are no more than 10 test cases.
For each test case, the first line contains n, the number of points on the trace in order. 1<=n<=1000.
Then n lines follow. Each line is a pair of integer x, y representing the n points' coordinates in order.
The last line contains three integers x,y and r descripting the Lake, The Lake is a circle. Its center is at (x,y) and its radius is r.
The input ends if n = 0.
All |x|, |y|, |r| are smaller than 107.
输出
For each test case, output the length of the border of the common area. Please round the answer to the closest integer.
- 样例输入
-
4
-10 -10
-10 10
10 10
10 -10
-10 -10 20
4
-10 -10
-10 10
10 10
10 -10
-10 -10 4
4
-10 -10
-10 10
10 10
10 -10
0 0 10
4
-40 -40
-40 40
40 40
40 -40
0 0 50
0 - 样例输出
-
71
14
63
297
#include <iostream>
#include <algorithm>
#include <string.h>
#include <math.h>
#include <cstdio>
using namespace std;
const double eps=0.000000000001;
const double PI=acos(-1.0);
const int maxn=;
int dcmp(double a)
{
if(fabs(a)<eps)return ;
else return a>?:-;
}
struct Point
{
double x,y;
Point(double cx=,double cy=)
{
x=cx; y=cy;
}
double ang;
void Angle()
{
ang=atan2(y,x);
if(ang<){
ang+=*PI;
}
}
bool operator <(const Point &rhs)const
{
return ang<rhs.ang;
}
};
struct Circle
{
Point c;
double r;
Circle(Point cc=Point(,),double cr=)
{
c=cc; r=cr;
}
Point point(double a)
{
return Point(c.x+cos(a)*r, c.y+sin(a)*r);
}
};
Point operator -(Point A, Point B)
{
return Point(A.x-B.x,A.y-B.y);
}
Point operator +(Point A, Point B)
{
return Point(A.x+B.x,A.y+B.y);
}
bool operator ==(const Point &A, const Point &B)
{
return dcmp(A.x-B.x) == && dcmp(A.y-B.y)==;
}
double Dot(Point A,Point B)
{
return A.x*B.x+A.y*B.y;
}
double Length(Point A)
{
return sqrt(Dot(A,A));
}
double Cross(Point A, Point B)
{
return A.x*B.y - A.y*B.x;
}
Point TE[maxn];
Circle C;
struct Ins{
Point c;
int id;
}Poi[maxn];
struct Line
{
Point p;
Point v;
Line(Point cp=Point(,),Point cv=Point(,))
{
p=cp; v=cv;
}
Point point(double a)
{
Point te=Point(v.x*a,v.y*a);
return p+te;
}
};
int getLineCicleIntersection(Line L,Circle C, double &t1,double &t2,Point &A,Point &B)
{
double a=L.v.x,
b=L.p.x-C.c.x,
c=L.v.y,
d=L.p.y-C.c.y;
double e=a*a+c*c,
f=*(a*b+c*d),
g=b*b+d*d-C.r*C.r;
double delta=f*f-*e*g;
if(dcmp(delta)<)return ;
if(dcmp(delta)==)
{
t1=t2=-f/(*e);A=L.point(t1);
return ;
}
t1=(-f - sqrt(delta))/(*e);
A=L.point(t1);
t2=(-f + sqrt(delta))/(*e);
B=L.point(t2);
return ;
}
int judjiaodian(int n)
{
int nu=;
double t1,t2;
Point A,B;
for(int i=; i<n; i++)
{
int ge=getLineCicleIntersection(Line(TE[i],TE[i+]-TE[i]),C,t1,t2,A,B);//计算直线和圆交点 大白书模板
if(ge==)continue;
double s=Length(TE[i]-TE[i+]);
double d1=Length(TE[i]-A);
double d2=Length(TE[i+]-A);
if(ge==){
if(dcmp(s-d1)>=&&dcmp(s-d2)>=) //判断是否在这条边上
{
Poi[nu].c=A; Poi[nu].id=i; nu++;
}
continue;
}
double d3=Length(TE[i]-B);
double d4=Length(TE[i+]-B);
if(dcmp(s-d1)>=&&dcmp(s-d2)>=&&dcmp(s-d3)>=&&dcmp(s-d4)>=)//如果存在两个点
{
if(d1>d3){//应该把离起点进的点放在前面
swap(A,B);
}
Poi[nu].c=A; Poi[nu].id=i;nu++;
Poi[nu].c=B; Poi[nu].id=i;nu++;
}else if(dcmp(s-d1)>=&&dcmp(s-d2)>=)
{
Poi[nu].c=A; Poi[nu].id=i;nu++;
}else if(dcmp(s-d3)>=&&dcmp(s-d4)>=)
{
Poi[nu].c=B; Poi[nu].id=i;nu++;
}
}
int ge=;
for(int i=; i<nu; i++)
if( (Poi[i].c==Poi[ge-].c) == false )
Poi[ge++]=Poi[i];
nu=ge;
return nu;
}
int isPointInpolygon(Point p,int n)//判断点是否在多边形内
{
int wn=;
for(int i=; i<n; i++)
{
int k=dcmp(Cross(TE[i+]-TE[i],p-TE[i]));
int d1=dcmp(TE[i].y -p.y );
int d2=dcmp(TE[i+].y-p.y);
if( k > && d1 <= && d2 > )wn++;
if( k < && d2 <= && d1 > )wn--;
}
if(wn!=)return ;
return ;
}
void solve(int n)
{
int numOfInCir=;
double dist=;
for(int i=; i<n; i++)
{
if( dcmp( C.r-Length(TE[i]-C.c) )>= )numOfInCir++;
dist+=Length( TE[i+]-TE[i] );
}
if(isPointInpolygon(C.c,n))
{
if(numOfInCir==n){
printf("%.0lf\n",dist);
}else printf("%.0lf\n",PI**C.r);
return;
}
if(numOfInCir == n)
{
printf("%.0lf\n",dist);
}else printf("0\n");
}
Point Hu[maxn];
double judsolveCir(int nu,int n)
{
for(int i=; i<nu; i++)
{
Hu[i]=Poi[i].c-C.c;
Hu[i].Angle();
}
sort(Hu,Hu+nu);
Hu[nu]=Hu[];
Hu[nu].ang+=*PI;
double ans=;
for(int i=; i<nu; i++)
{
double ang=(Hu[i].ang+Hu[i+].ang)/;
if(ang>*PI)ang-=*PI;
Point t =C.point(ang);
if(isPointInpolygon(t,n))
{
ang=Hu[i+].ang-Hu[i].ang;
ans+=ang*C.r;
}
}
return ans;
}
Point TP[maxn];
double judsolvePoly(int nu, int n)
{
int loc=,num=;
for(int i=; i<n; i++)//融合那些点
{
TP[num++]=TE[i];
while(loc<nu&&Poi[loc].id<=i){
TP[num++]=Poi[loc].c; loc++;
}
}
loc=;
for(int i=; i<num; i++)
if((TP[i]==TP[loc-])==false )TP[loc++]=TP[i];
num=loc;
TP[num]=TP[];
double ans=;
for(int i=; i<num; i++)
{
Point tt=TP[i]+TP[i+];
tt.x*=0.5;
tt.y*=0.5;
double d1=Length(C.c-tt);
if(dcmp(C.r-d1)>=){
ans+=Length(TP[i+]-TP[i]);
}
}
return ans;
}
int main()
{
int n;
while(scanf("%d",&n)==&&n)
{
for(int i=; i<n; i++)
scanf("%lf%lf",&TE[i].x,&TE[i].y);
TE[n]=TE[];
scanf("%lf%lf%lf",&C.c.x,&C.c.y,&C.r);
int nu=judjiaodian(n);//计算交点
if(nu==||nu==){
solve(n);// 特判那几种情况
continue;
}
double ans=judsolveCir(nu,n);// 计算圆在多边形内的部分
ans+=judsolvePoly(nu,n);// 计算多边形在圆内的部分
printf("%.0lf\n",ans);
}
return ;
}
题意:
2015 北京网络赛 E Border Length hihoCoder 1231 树状数组 (2015-11-05 09:30)的更多相关文章
- 2015北京网络赛 D-The Celebration of Rabbits 动归+FWT
2015北京网络赛 D-The Celebration of Rabbits 题意: 给定四个正整数n, m, L, R (1≤n,m,L,R≤1000). 设a为一个长度为2n+1的序列. 设f(x ...
- 2015北京网络赛 J Scores bitset+分块
2015北京网络赛 J Scores 题意:50000组5维数据,50000个询问,问有多少组每一维都不大于询问的数据 思路:赛时没有思路,后来看解题报告也因为智商太低看了半天看不懂.bitset之前 ...
- 2015北京网络赛 Couple Trees 倍增算法
2015北京网络赛 Couple Trees 题意:两棵树,求不同树上两个节点的最近公共祖先 思路:比赛时看过的队伍不是很多,没有仔细想.今天补题才发现有个 倍增算法,自己竟然不知道. 解法来自 q ...
- hihocoder 1391 树状数组
#1391 : Countries 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 There are two antagonistic countries, countr ...
- 2015 北京网络赛 C Protecting Homeless Cats hihoCoder 1229 树状数组
题意:求在平面上 任意两点连线,原点到这个点的距离小于d的点对有多少个,n=200000; 解: 以原点为圆心做一个半径为d的圆,我们知道圆内的点和园内以外的点的连线都是小于d的还有,圆内和园内的点联 ...
- hihocoder 1236(2015北京网络赛 J题) 分块bitset乱搞题
题目大意: 每个人有五门课成绩,初始给定一部分学生的成绩,然后每次询问给出一个学生的成绩,希望知道在给定的一堆学生的成绩比这个学生每门都低或者相等的人数 因为强行要求在线查询,所以题目要求,每次当前给 ...
- 2015北京网络赛B题 Mission Impossible 6
借用大牛的一张图片:模拟 #include<cstdio> #include<cmath> #include<cstring> #include<algori ...
- 2015北京网络赛 F Couple Trees 暴力倍增
Couple Trees Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://hihocoder.com/problemset/problem/123 ...
- 2015北京网络赛 J Clarke and puzzle 求五维偏序 分块+bitset
Clarke and puzzle Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://hihocoder.com/contest/acmicpc20 ...
随机推荐
- Manual Validation with Data Annotations C#对实体类进行手动验证
Several people have asked me about using data annotations for validation outside of a UI framework, ...
- PHPExcel所遇到问题的知识点总结
工作中进行excel的时候遇到了两个问题, 1.excel表中列值过大,由于没有进行特殊处理,程序没法正常运行: 2.列值中含有日期格式的文本,不能正确读取: 所以通过网络搜索,并解决了问题,记录一下 ...
- Laravel 深入理解路由和URL生成
原文地址: Laravel 深入理解路由和URL生成 在模板中我们一般不会直接写死url,而是用url助手生成url,本文介绍一下url助手的使用以及遇到的一些比较头疼的问题. 首先,我们创建了一个路 ...
- 提高MySQL数据库的安全性
1. 更改默认端口(默认3306) 可以从一定程度上防止端口扫描工具的扫描 2. 删除掉test数据库 drop database test; 3. 密码改的复杂些 # 1 set password ...
- 【App】不通过App Store实现ios应用分发下载安装(转)
转自:https://www.cnblogs.com/star91/p/5018995.html 最近公司的项目准备着手宣传工作了,宣传手册上要印制App的下载地址二维码,但是客户端应用还未上线, ...
- C# 鼠标移动Winform窗体内或者panel容器内的控件 显示虚线/实现虚线框来确定位置
C# 鼠标移动WinForm窗体或者panel容器内的控件 移动虚线/实现虚线框来确定位置 1.用到的方法介绍 今天,根据领导指示指导移动容器内的控件,生成虚线框,使用 ControlPaint.Dr ...
- [VS SVN] VS的SVN插件AnkhSvn
VS的SVN插件AnkhSvn 修改VS配置 将解决方案或项目加入SVN管理
- js模拟发送 FormData数据
后台express需要connect-multiparty模块接收formData的数据类型 class ourFormData { constructor(data, rs) { return ne ...
- 大臣的旅费---树的直径(dfs)
很久以前,T王国空前繁荣.为了更好地管理国家,王国修建了大量的快速路,用于连接首都和王国内的各大城市. 为节省经费,T国的大臣们经过思考,制定了一套优秀的修建方案,使得任何一个大城市都能从首都直接或者 ...
- 谷歌浏览器(Chrome)禁止浏览器缓存 设置
在开发项目期间用谷歌浏览器调试,他总是缓存我的css样式这个很气人啊,后经过摸索找到了方法,如下 先F12或者shift+ctrl+j 打开调试者工具,在找Network这个tab按钮,点击进入,勾选 ...