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 ...
随机推荐
- 关于Unity中物体分别在本地和世界坐标系对应方向的移动
方向 Vector3可以定义以世界坐标轴为参考的三维矢量,Vector3.forward,Vector3.up,Vector3.right方别对应物体世界坐标系的Z,Y,X轴方向的单位向量,或者叫三维 ...
- 解决vscode无法提示golang的问题
https://github.com/Microsoft/vscode-go/wiki/Go-with-VS-Code-FAQ-and-Troubleshooting Q: Auto-completi ...
- A claim of type 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier' or 'http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider' was not present on the pro
Try setting (in global.cs): AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier; ...
- 内建模块collections的使用
# -*-coding:utf-8 -*- from collections import namedtuple Point=namedtuple('Point',['x','y']) p=Point ...
- python机器学习包 Windows下 pip安装 scikit-learn numpy scipy
1.到PIP的目录中C:\Python34\Scripts;2. 2.1 pip安装numpy pip install numpy 2.2 pip安装sklearn pip install -U ...
- 获取mssqlserver数据库表的字段名称,字段说明,数据类型,主键等表的信息
sql脚本: SELECT TableName then d.name else '' end,---表名 TableShowsThat then isnull(f.value,'') else '' ...
- 删除JS 对象属性(元素)
var a={"id":1,"name":"danlis"}; //添加属性 a.age=18; console.log(a); //结果: ...
- linux 之挂载和解压
第3天 磁盘管理 存储设备:硬盘.U盘.移动硬盘.光盘.软盘. 攒电脑.(组装一台电脑) 无法被修改. 矿长.欧阳大神. 分区.->格式化ntfs df -h #查看磁盘分区情况,可用的. 查 ...
- Tanya and Candies
Tanya and Candies time limit per test 1 second memory limit per test 256 megabytes input standard in ...
- Hibernate配置关系(申明:来源于csdn)
hibernate中多对一.一对一.一对多.多对多的配置方法 地址:http://blog.csdn.net/communicate_/article/details/8445437