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表示这种切法可以切 ...
随机推荐
- Invalid file system control data detected
今天在做mkdir操作时报错:Invalid file system control data detected.检查用户和权限没问题,再检查磁盘空间也没问题.最后在网上找到如下信息: [proble ...
- 大型分布式C++框架《一:框架简介》
首先名字要取得霸气才能吸引人气,哈哈~~ 下面简单介绍下情况.框架是腾讯电商平台的分布式框架.虽然腾讯拍拍已经玩完了.但是这套框架还是很不错的.而且据原腾讯同事说微信也是用的这套框架.源码肯定是不能说 ...
- C# 文件上传
一.分析 本次博客,主要解决文件上传等一系列问题,将从两方面来论述,即1G以内文件和1G以上文件. 对于上传1G以内的文件,可以采用基本的三种上传方法:用Web控件FileUpload.html控件 ...
- Myeclipse自动生成javabean的get和set方法
用Myeclipse开发java web程序,写javabean的时候,如果字段很多的话,写get和set方法是一件很无语和浪费时间的事情,所以Myeclipse提供了一个自动生成这些方法的功能. 首 ...
- 重写boost内存池
最近在写游戏服务器网络模块的时候,需要用到内存池.大量玩家通过tcp连接到服务器,通过大量的消息包与服务器进行交互.因此要给每个tcp分配收发两块缓冲区.那么这缓冲区多大呢?通常游戏操作的消息包都很小 ...
- iOS--九宫格布局
[self rankWithTotalColumns: andWithAppW: andWithAppH:]; //九宫格布局 - (void)rankWithTotalColumns:(int)to ...
- jquery1.7.2的源码分析(五)$.support
$.support 的英文注释很详细的介绍的这里,就稍微的写了下 Query.support = (function() { var support, all, a, select, opt, inp ...
- es6新特性:
http://es6katas.org/ es6+一些新特性,截图如下 对应方法,函数显示相关的数据,如图: 对应方法,函数的例子,如下
- (转)利用ant在Mac 下自动化打包签名Android程序
1.创建一个android项目 参数说明:-k /--package 为命名空间(包名)-a /--name 工程名-p /--path 项目 -t 为目标平台的版本编号 命令:./android c ...
- [转]Android访问网络,使用HttpURLConnection还是HttpClient
转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/12452307 最近在研究Volley框架的源码,发现它在HTTP请求的使用上比较有 ...