Building Fence

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)
Total Submission(s): 171    Accepted Submission(s): 25
Special Judge

Problem Description
Long long ago, there is a famous farmer named John. He owns a big farm and many cows. There are two kinds of cows on his farm, one is Friesian, and another one is Ayrshire. Each cow has its own territory. In detail, the territory of Friesian is a circle, and of Ayrshire is a triangle. It is obvious that each cow doesn't want their territory violated by others, so the territories won't intersect.

Since the winter is falling, FJ has to build a fence to protect all his cows from hungry wolves, making the territory of cows in the fence. Due to the financial crisis, FJ is currently lack of money, he wants the total length of the fence minimized. So he comes to you, the greatest programmer ever for help. Please note that the part of fence don't have to be a straight line, it can be a curve if necessary.

 
Input
The input contains several test cases, terminated by EOF. The number of test cases does not exceed 20.
Each test case begins with two integers N and M(0 ≤ N, M ≤ 50, N + M > 0)which denotes the number of the Friesian and Ayrshire respectively. Then follows N + M lines, each line representing the territory of the cow. Each of the first N lines contains three integers Xi, Yi, Ri(1 ≤ Ri ≤ 500),denotes the coordinates of the circle's centre and radius. Then each of the remaining M lines contains six integers X1i, Y1i, X2i, Y2i, X3i, Y3i, denotes the coordinates of the triangle vertices. The absolute value of the coordinates won't exceed 10000.
 
Output
For each test case, print a single line containing the minimal fence length. Your output should have an absolute error of at most 1e-3.
 
Sample Input
1 1
4 4 1
0 0 0 2 2 0
 
Sample Output
15.66692

Hint

Please see the sample picture for more details, the fence is highlighted with red.

 
Source
 
Recommend
zhuyuanchen520
 

标程的正解应该是找圆上的关键点。

两圆两两的切点,和三角形上的点和圆的切点是关键点。

然后所有点求凸包。

如果两个关键点刚好在一个圆上,用圆弧长度代替距离。

我的做法是没有求关键点,直接把圆均匀分成1000个点,然后就水过了。

 /* **********************************************
Author : kuangbin
Created Time: 2013/8/13 14:13:06
File Name : F:\2013ACM练习\2013多校7\1002.cpp
*********************************************** */ #include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
using namespace std; const double eps = 1e-;
const double PI = acos(-1.0);
int sgn(double x)
{
if(fabs(x) < eps)return ;
if(x < )return -;
else return ;
}
struct Point
{
double x,y;
int index;
Point(){}
Point(double _x,double _y,int _index)
{
x = _x;y = _y;index = _index;
}
Point(double _x,double _y)
{
x = _x;y = _y;
}
Point operator -(const Point &b)const
{
return Point(x - b.x,y - b.y);
}
//叉积
double operator ^(const Point &b)const
{
return x*b.y - y*b.x;
}
//点积
double operator *(const Point &b)const
{
return x*b.x + y*b.y;
}
//绕原点旋转角度B(弧度值),后x,y的变化
void transXY(double B)
{
double tx = x,ty = y;
x = tx*cos(B) - ty*sin(B);
y = tx*sin(B) + ty*cos(B);
}
}; //*两点间距离
double dist(Point a,Point b)
{
return sqrt((a-b)*(a-b));
} /*
* 求凸包,Graham算法
* 点的编号0~n-1
* 返回凸包结果Stack[0~top-1]为凸包的编号
*/
const int MAXN = ;
Point list[MAXN];
int Stack[MAXN],top;
//相对于list[0]的极角排序
bool _cmp(Point p1,Point p2)
{
double tmp = (p1-list[])^(p2-list[]);
if(sgn(tmp) > )return true;
else if(sgn(tmp) == && sgn(dist(p1,list[]) - dist(p2,list[])) <= )
return true;
else return false;
}
void Graham(int n)
{
Point p0;
int k = ;
p0 = list[];
//找最下边的一个点
for(int i = ;i < n;i++)
{
if( (p0.y > list[i].y) || (p0.y == list[i].y && p0.x > list[i].x) )
{
p0 = list[i];
k = i;
}
}
swap(list[k],list[]);
sort(list+,list+n,_cmp);
if(n == )
{
top = ;
Stack[] = ;
return;
}
if(n == )
{
top = ;
Stack[] = ;
Stack[] = ;
return ;
}
Stack[] = ;
Stack[] = ;
top = ;
for(int i = ;i < n;i++)
{
while(top > && sgn((list[Stack[top-]]-list[Stack[top-]])^(list[i]-list[Stack[top-]])) <= )
top--;
Stack[top++] = i;
}
}
const int NUM = ;
int X[],Y[],R[];
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int N,M;
while(scanf("%d%d",&N,&M) == )
{ for(int i =;i < N;i++)
{
scanf("%d%d%d",&X[i],&Y[i],&R[i]);
for(int j = ;j < NUM;j++)
{
double tmp = *PI*j/NUM;
list[j+i*NUM] = Point( X[i] + R[i]*cos(tmp),Y[i] + R[i]*sin(tmp),i );
} }
int x,y;
for(int i = ;i < M;i++)
{
scanf("%d%d",&x,&y);
list[N*NUM+i*] = Point(x,y,-);
scanf("%d%d",&x,&y);
list[N*NUM+i*+] = Point(x,y,-);
scanf("%d%d",&x,&y);
list[N*NUM+i*+] = Point(x,y,-);
}
Graham(N*NUM+M*);
double ans = ;
//cout<<top<<endl;
for(int i = ;i < top;i++)
{
int t1 = Stack[i];
int t2 = Stack[(i+)%top];
// cout<<t1<<" "<<t2<<endl;
// printf("%.2lf %.2lf\n",list[t1].x,list[t2].y);
if(list[t1].index != - && list[t2].index == list[t1].index)
{
int tt = list[t1].index;
ans += R[tt]**PI/(NUM);
}
else ans += dist(list[t1],list[t2]);
}
printf("%.5lf\n",ans);
}
return ;
}

HDU 4667 Building Fence(2013多校7 1002题 计算几何,凸包,圆和三角形)的更多相关文章

  1. HDU 4643 GSM (2013多校5 1001题 计算几何)

    GSM Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Submiss ...

  2. HDU 4667 Building Fence(求凸包的周长)

    A - Building Fence Time Limit:1000MS     Memory Limit:65535KB     64bit IO Format:%I64d & %I64u ...

  3. HDU 4705 Y (2013多校10,1010题,简单树形DP)

    Y Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submiss ...

  4. HDU 4704 Sum (2013多校10,1009题)

    Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submi ...

  5. HDU 4699 Editor (2013多校10,1004题)

    Editor Time Limit: 3000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Su ...

  6. HDU 4696 Answers (2013多校10,1001题 )

    Answers Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total S ...

  7. HDU 4678 Mine (2013多校8 1003题 博弈)

    Mine Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Submis ...

  8. HDU 4681 String(2013多校8 1006题 DP)

    String Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Subm ...

  9. HDU 4666 Hyperspace (2013多校7 1001题 最远曼哈顿距离)

    Hyperspace Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Tota ...

随机推荐

  1. 【UOJ#38】【清华集训2014】奇数国

    考虑欧拉函数的性质,60很小,压位存下线段树每个节点出现质数. #include<bits/stdc++.h> ; ; typedef long long ll; using namesp ...

  2. PDO和mysqli对比

    PHP中,如何选择PDO和mysqli呢?本文做个简单的比较 1)总的比较   PDO MYSQLI 数据库支持 12种不同的数据库支持 支持MYSQL API OOP OOP和过程 命名参数 支持 ...

  3. xss 过滤

    一. xss过滤 用户通过Form获取展示在终端, 提交数据,Form验证里面加入xss验证(对用户提交的内容验证是否有关键标签) from django.conf.urls import url f ...

  4. kali&BT安装好之后无法上网(包括Wifi)或者无法获得内网IP解决方法

    大家都知道,要想进行内网渗透攻击,你必须要在那个内网里.但是大家在Vmware里安装kali的时候,大多数用户为了方便,未选择桥接模式,而是选择了使用与本机共享的IP网络当然,这样能上网,但是你的虚拟 ...

  5. Mybatis基础及入门案例

    这几天正在对SSM框架的知识进行一个回顾加深,有很多东西学的囫囵吞枣,所以利用一些时间进一步的学习.首先大概了解一下mybatis的使用,再通过一个案例来学习它. 什么是MyBatis Mybatis ...

  6. OPENSSL问题,使用fsockopen()函数提示错误

    环境配置 系统环境 CentOS7.2WDCP v3.2.2 lanmp PHP 多版本 指定使用5.6 OpenSSL 1.0.2h  3 May 2016 php.ini相关设置allow_url ...

  7. 诺基亚9 PureView正式发布

    [手机中国新闻]当地时间2月24日下午16点,HMD在西班牙巴塞罗那正式发布了诸多新品,其中最吸睛的莫过于Nokia 9 PureView.作为全球首款五摄新机,Nokia 9 PureView后置五 ...

  8. day4 二维数组旋转90度

    二维数组的旋转其实就是数组里面的元素对调的情况:下面有一个4×4的二维数组,[[0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3]],现在要求把 ...

  9. Roman to Integer & Integer to Roman

    题目: Given a roman numeral, convert it to an integer. Input is guaranteed to be within the range from ...

  10. 开发 ASP.NET vNext 初步总结(使用Visual Studio 2015 Preview )

    新特性: vNext又称MVC 6.0,不再需要依赖System.Web,占用的内存大大减少(从前无论是多么简单的一个请求,System.Web本身就要占用31KB内存). 可以self-host模式 ...