hdu 3511
来源:互联网 发布:完整的数据库源代码 编辑:程序博客网 时间:2024/06/05 07:23
题目意思实际上就是找嵌套数最大的圆并输出其嵌套数。
一开始见时间有5000ms,就果断暴力,然后果断超时— — 之后用二分,终于不tle啦,但wa。。。TAT。上网找题解,发现有两种方法,一个是用随机数,另一个是计算几何中的扫描法,其中用了set,没见过,于是好好学习了一下,发现思想还是很好懂的,该解法的所在地址是:
http://hi.baidu.com/bobobry/blog/item/e270bf097b3bd9376b60fbbe.html
以下是计算几何的解法:
#include<cstdio>#include<cstring>#include<stdlib.h>#include<set>#include<cmath>using namespace std;const int M=50100;int max(int a,int b) {return a>b?a:b;}int n,t;struct cirs{ int x,y; int r,w;}cir[M];struct event{ int x; int id,mark; //mark为1,则圆为运算对象,反之,圆要删出set}eve[2*M];int nowx;double cacul(int id,int mark){ double d; d=sqrt((double)cir[id].r*cir[id].r-(double)(nowx-cir[id].x)*(nowx-cir[id].x)); return mark?(double)cir[id].y+d:(double)cir[id].y-d;}bool equal(double a,double b){ if(fabs(a-b)<1e-8) return 1; else return 0;}struct nodes{ int id; int mark; bool operator<(const nodes a)const //set的<要重载 { double y1=cacul(id,mark); double y2=cacul(a.id,a.mark); return y1>y2 || equal(y1,y2) && mark>a.mark; }};set<nodes> line;set<nodes>::iterator it,pre,succ;int cmp(const void *a,const void *b){ int t; struct event *x,*y; x=(struct event *)a; y=(struct event *)b; t=x->x-y->x; if(t!=0) return t; else t=cir[y->id].y-cir[x->id].y; return t;}void move_line() //计算几何中的扫描法{ line.clear(); int i,j; for(i=0;i<t;i++) { nowx=eve[i].x; if(eve[i].mark==1) //这个圆没运算过 { struct nodes node; node.id=eve[i].id; node.mark=1; it=line.insert(node).first; succ=pre=it; succ++; if(it==line.begin() || succ==line.end()) { cir[it->id].w=1; //此时是最外层的圆 } else //当前圆嵌套与前一个圆中 { pre--; if(pre->id==succ->id) { cir[it->id].w=cir[pre->id].w+1; } else //处于同一嵌套级别的圆的嵌套数 { cir[it->id].w=max(cir[pre->id].w,cir[succ->id].w); } } struct nodes node2; node2.id=eve[i].id; node2.mark=0; line.insert(node2).second; } else //该圆的右点以被扫描到,该离开set了 { struct nodes node,node2; node.id=eve[i].id; node.mark=1; line.erase(node); node2.mark=0; node2.id=eve[i].id; line.erase(node2); } }}int main(){// freopen("in.txt","r",stdin); int i,j; while(scanf("%d",&n)==1) { t=0; for(i=0;i<n;i++) { scanf("%d%d%d",&cir[i].x,&cir[i].y,&cir[i].r); cir[i].w=0; eve[t].x=cir[i].x-cir[i].r; eve[t].id=i; eve[t].mark=1; t++; eve[t].x=cir[i].x+cir[i].r; eve[t].id=i; eve[t].mark=0; t++; } qsort(eve,t,sizeof(eve[0]),cmp); move_line(); int ans=-1; for(i=0;i<n;i++) { if(cir[i].w>ans) ans=cir[i].w; } printf("%d\n",ans); } return 0;}
接下的这份随机函数的代码就真的很考验rp的哈,我交了8次才过了3次。。。两次是直接拿那位大牛的来交的。。。。
#include<cstdio>#include<cstring>#include <cstdlib>#include<ctime>#include<iostream>using namespace std;const int M=50000;struct cir{ double x,y,r;}c[M];bool vis[M];int n;int main(){ srand((unsigned)time(NULL)); while(scanf("%d",&n)==1) { int i,j,ans=-1; for(i=0;i<n;i++) scanf("%lf%lf%lf",&c[i].x,&c[i].y,&c[i].r); memset(vis,0,sizeof(vis)); int tmp=1; for(j=1;j<n;j++) { if((c[0].x-c[j].x)*(c[0].x-c[j].x)+(c[0].y-c[j].y)*(c[0].y-c[j].y)<c[j].r*c[j].r) tmp++; } if(tmp>ans) tmp=ans; int rd; for(i=0;i<n && i<5000 && ans!=n;) { rd=rand()%n; if(vis[rd]) continue; vis[rd]=1; i++; tmp=1; for(j=0;j<n;j++) { if(rd==j) continue; if((c[rd].x-c[j].x)*(c[rd].x-c[j].x)+(c[rd].y-c[j].y)*(c[rd].y-c[j].y)<c[j].r*c[j].r) tmp++; } if(tmp>ans) ans=tmp; } printf("%d\n",ans); } return 0;}
- hdu 3511
- hdu 3511 Prison Break
- HDU 3511扫描线
- HDU 3511 Prison Break
- hdu 3511 圆扫描线
- hdu
- hdu
- HDU
- hdu ()
- hdu
- hdu
- HDU
- HDU
- hdu
- hdu
- HDU
- Hdu
- hdu
- 人生中重要的经历4
- 【转】探索推荐引擎内部的秘密
- 男人城府的修练.
- 嵌套删除非空目录
- INSTALL_FAILED_OLDER_SDK
- hdu 3511
- 编译U-boot 出现 undefined reference to `dm9000_initialize' 的问题
- 谈谈我所理解的IT界的云
- USACO算法系列——Big Barn
- c++析构函数
- JAVA IO系列----FileInputStream和FileOutputStream类,Reader和Writer类
- 提高编程技能最有效的方法
- PyCon 2011 - Hidden Treasures of the Python Standard Library - 模拟hmac摘要算法的实现
- android.intent.action大全