HDU 4116 Fruit Ninja
http://acm.hdu.edu.cn/showproblem.php?pid=4116
题意:给N个圆,求一条直线最多能经过几个圆?(相切也算)
思路:枚举中心圆,将其他圆的切线按照极角排序,并赋上权值(1\-1),那么我们for一遍,sum随时加上权值,当sum最大时,就可以更新答案。
#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<cstring>
const double eps=1e-;
const double Pi=acos(-);
int n;
struct Point{
double x,y,r;
Point(){}
Point(double x0,double y0,double r0):x(x0),y(y0),r(r0){}
Point(double x0,double y0):x(x0),y(y0){}
}p[];
bool vis[];
struct Line{
int id,c;
double ang;
Line(){}
Line(int id0,int c0,double ang0):id(id0),c(c0),ang(ang0){}
}L[];
int sgn(double x){
if (x>eps) return ;
if (x<-eps) return -;
return ;
}
double fix(double x){
while (sgn(x)<) x+=2.0*Pi;
while (sgn(x-Pi-Pi)>=) x-=2.0*Pi;
return x;
}
bool cmp(Line p1,Line p2){
int tmp=sgn(p1.ang-p2.ang);
if (tmp) return tmp<;
else return p1.c>p2.c;
}
int read(){
int t=,f=;char ch=getchar();
while (ch<''||ch>''){if (ch=='-') f=-;ch=getchar();}
while (''<=ch&&ch<=''){t=t*+ch-'';ch=getchar();}
return t*f;
}
Point operator -(Point p1,Point p2){
return Point(p1.x-p2.x,p1.y-p2.y,);
}
double sqr(double x){
return x*x;
}
double dist(Point p){
return sqrt(sqr(p.x)+sqr(p.y));
}
double dist(Point p1,Point p2){
return dist(p1-p2);
}
Point getPoint(Point p,double ang){
return Point(p.x+cos(ang)*p.r,p.y+sin(ang)*p.r);
}
void cut_line(Point &A,Point &B,int &id,int &sum,int &len){
double dis=dist(A,B);
double Base=atan2(B.y-A.y,B.x-A.x);
if (sgn(A.r-B.r-dis)>) return;
if (sgn(B.r-A.r-dis)>=){
sum++;return;
}
double ang1=asin((B.r-A.r)/dis);
double ang2=asin((B.r+A.r)/dis);
if (sgn(A.r+B.r-dis)>=){
L[++len]=Line(id,,fix(Base-ang1));
L[++len]=Line(id,-,fix(Base+ang1+Pi));
return;
}
L[++len]=Line(id,,fix(Base-ang1));
L[++len]=Line(id,-,fix(Base+ang1+Pi));
L[++len]=Line(id,-,fix(Base+ang2));
L[++len]=Line(id,,fix(Base-ang2+Pi));
return;
}
int work(int n,int len){
int res=;
int sum=;
memset(vis,false,sizeof(bool)*(n+));
for (int i=;i<=(len<<);i++){
int k=(i>len)?i-len:i;
int id=L[k].id;
int c=L[k].c;
if (c==){
if (!vis[id]){
vis[id]=true;
sum++;
}
}else{
if (vis[id]){
vis[id]=false;
sum--;
}
}
if (sum>res) res=sum;
}
return res;
}
int main(){
int T=read(),Tcase=;
while (T--){
n=read();printf("Case #%d: ",++Tcase);
for (int i=;i<=n;i++)
scanf("%lf%lf%lf",&p[i].x,&p[i].y,&p[i].r);
int ans=;
for (int i=;i<=n;i++){
int len=;int sum=;
for (int j=;j<=n;j++) if (i!=j)
cut_line(p[i],p[j],j,sum,len);
std::sort(L+,L++len,cmp);
sum+=work(n,len);
ans=std::max(ans,sum);
}
printf("%d\n",ans);
}
return ;
}
HDU 4116 Fruit Ninja的更多相关文章
- HDU 4116 Fruit Ninja ( 计算几何 + 扫描线 )
给你最多1000个圆,问画一条直线最多能与几个圆相交,相切也算. 显然临界条件是这条线是某两圆的公切线,最容易想到的就是每两两圆求出所有公切线,暴力判断一下. 可惜圆有1000个,时间复杂度太高. 网 ...
- hdu 4000 Fruit Ninja 树状数组
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4000 Recently, dobby is addicted in the Fruit Ninja. ...
- hdu 4620 Fruit Ninja Extreme
Fruit Ninja Extreme Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...
- HDU 4620 Fruit Ninja Extreme 搜索
搜索+最优性剪枝. DFS的下一层起点应为当前选择的 i 的下一个,即DFS(i + 1)而不是DFS( cur + 1 ),cur+1代表当前起点的下一个.没想清楚,TLE到死…… #include ...
- hdu - 3952 Fruit Ninja(简单几何)
思路来自于:http://www.cnblogs.com/wuyiqi/archive/2011/11/06/2238530.html 枚举两个多边形的两个点组成的直线,判断能与几个多边形相交 因为最 ...
- HDU 4000 Fruit Ninja 树状数组 + 计数
给你N的一个排列,求满足:a[i] < a[k] < a[j] 并且i < j < k的三元组有多少个. 一步转化: 求出所有满足 a[i] < a[k] < a[ ...
- HDU 4620 Fruit Ninja Extreme(2013多校第二场 剪枝搜索)
这题官方结题报告一直在强调不难,只要注意剪枝就行. 这题剪枝就是生命....没有最优化剪枝就跪了:如果当前连续切割数加上剩余的所有切割数没有现存的最优解多的话,不需要继续搜索了 #include &l ...
- hdu 4620 Fruit Ninja Extreme(状压+dfs剪枝)
对t进行从小到大排序(要记录ID),然后直接dfs. 剪枝的话,利用A*的思想,假设之后的全部连击也不能得到更优解. 因为要回溯,而且由于每次cut 的数目不会超过10,所以需要回溯的下标可以利用一个 ...
- HDU 4620 Fruit Ninja Extreme 暴搜
题目大意:题目就是描述的水果忍者. N表示以下共有 N种切水果的方式. M表示有M个水果需要你切. W表示两次连续连击之间最大的间隔时间. 然后下N行描述的是 N种切发 第一个数字C表示这种切法可以切 ...
随机推荐
- mysql redo log
mysql> show variables like '%innodb_log_file_size%'; +----------------------+-----------+ | Varia ...
- STL_vector
1.任何改变vector长度的操作都会使已经存在的迭代器失效 vector是C++标准模板库中的部分内容,它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库.vector之所以被认为是一个容 ...
- 你应该了解的 7个Linux ls 命令技巧
在前面我们系列报道的两篇文章中,我们已经涵盖了关于‘ls’命令的绝大多数内容.本文时‘ls命令’系列的最后一部分.如果你还没有读过该系列的其它两篇文章,你可以访问下面的链接. 15 个‘ls’命令的面 ...
- ubuntu下安装pdo扩展
ubuntu下安装好LAMP后默认情况没有安装mysql_pdo扩展,以下是安装 步聚,在终端输入以下命令 1.pecl search pdo 2.sudo pecl install pdo 当出现E ...
- Java中setCharAt()方法介绍
--转载自网络,备忘 这是StringBuffer类里面的一个方法:主要是用来替换的,方法里面有两个参数setCharAt(int index,Char ch),第一个参数是取代的位置 索引从0开始 ...
- Python进阶(面向对象编程基础)(三)
6.类属性和实例属性名字冲突怎么办 修改类属性会导致所有实例访问到的类属性全部都受影响,但是,如果在实例变量上修改类属性会发生什么问题呢? class Person(object): address ...
- C++编程规范之19:总是初始化变量
摘要: 一切从白纸开始,未初始化的变量是C和C++程序中错误的常见来源.养成在使用内存之前先清除的习惯,可以避免这种错误,在定义变量的时候就将其初始化. 按照C和C++相同的低层高效率传统,通常并不要 ...
- ADT下载地址整理
參考以下文章 http://developer.android.com/tools/sdk/eclipse-adt.html 整理了官网的下载地址 http://dl.google.com/andro ...
- CSS3动画(360度旋转、旋转放大、放大、移动)
Title div { width: 120px; height: 120px; line-height: 120px; margin: 20px; background-color: #5cb85c ...
- 转载——CLR标量函数、表值函数和聚合函数(UDA)
本节主要介绍使用CLR创建标量函数,表值函数和聚合函数. 所谓标量函数指的就是此函数只返回一个值.表值函数返回值是一个表.聚合函数是在select语句中使用的,用来聚合一个结果集,类似于Sum()或是 ...