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 ...
随机推荐
- 理解和解决Java并发修改异常ConcurrentModificationException(转载)
原文地址:https://www.jianshu.com/p/f3f6b12330c1 理解和解决Java并发修改异常ConcurrentModificationException 不知读者在Java ...
- ABBYY PDF Transformer+支持的格式
ABBYY PDF Transformer+是一个新的,全面的巧妙解决PDF文档的工具,它将泰比的光学字符识别(OCR)技术和Adobe®PDF技术完美结合,以确保实现便捷地处理任何类型的PDF文件, ...
- php处理数据分组问题
很简单的一个需求,将数据库取出的二维数组进行按照id分组,同组的数据用逗号连接,例如: 处理为 就是按照id分组,name进行逗号拼接. 那么按照数据库的思路来说,采用group_concat即可,如 ...
- js 注意
1.如果想要动态加清除浮动的代码,可以这样做: document.getElementById("mainBody").innerHTML += "<div sty ...
- IntelliJ IDEA 2018.3.2无法正常输入字符问题解决方案
昨天升级IDEA的版本到2018.3.2,今天打开项目发现只要在代码编辑器输入字符(英文.符号或中文等)都会立刻被强制删除,造成一个无法正常输入的现象(回车换行可以).仔细观察这种想象后发有可能是代码 ...
- js中 变量的解构赋值
es6新特性, 提取数组或对象中的值,按照对应位置, 为变量赋值. let [a, b, c] = [1, 2, 3]; 交换变量的值变得容易 let x = 1; let y = 2; [x, y] ...
- Java9之HashMap与ConcurrentHashMap
HashMap在Java8之后就不再用link data bins了,而是转为用Treeify的bins,和之前相比,最大的不同就是利用了红黑树,所以其由 数组+链表+红黑树 组成.: * This ...
- ubuntu下安装go环境
1.官网下载go语言安装包 地址:https://studygolang.com/dl 2.服务器上安装go 将下载下来的安装包解压到/usr/local下 tar xf go1.12.1.linux ...
- js运用3
1. js的本质就是处理数据.数据来自于后台的数据库. 所以变量就起到一个临时存储数据的作用. ecmascript制定了js的数据类型. 数据类型有哪些? 1. 字符串 string 2. 数字 n ...
- python全栈开发 * 进程之间的通信,进程之间数据共享 * 180726
进程之间的通信(IPC)队列和管道一.队列 基于管道实现 管道 + 锁 数据安全(一).队列 队列遵循先进先出原则(FIFO) 多用于维护秩序,买票,秒杀 队列的所有方法: put()(给队列里添加数 ...