BZOJ4642 泡泡

来源:互联网 发布:linux内存管理详解 编辑:程序博客网 时间:2024/03/29 12:55

这题……一看圆不相交,直观上可以扫描线,每次插入和删除的时候判一下相邻的是否相切,然后……大概证一下,好像可以扫描线,然后写一发A了,发现确实可以扫描线……

注意写扫描线的比较函数的时候考虑各种相等情况

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<ctime>#include<cmath>#include<algorithm>#include<iomanip>#include<vector>#include<map>#include<set>#include<bitset>#include<queue>#include<stack>using namespace std;#define MAXN 500010#define MAXM 1010#define INF 1000000000#define MOD 1000000007#define eps 1e-8#define ll long longstruct cir{double x;double y;double r;};struct evt{double x;int bel;int c;friend bool operator <(evt x,evt y){return fabs(x.x-y.x)>eps?x.x<y.x:x.c<y.c;}};cir c[MAXN];struct pt{int bel;int cl;pt(){}pt(int _bel,int _cl){bel=_bel;cl=_cl;}double y();friend bool operator <(pt x,pt y){return x.bel==y.bel?x.cl<y.cl:fabs(x.y()-y.y())>eps?x.y()<y.y():c[x.bel].y!=c[y.bel].y?c[x.bel].y<c[y.bel].y:x.bel<y.bel;}};int X;evt e[MAXN*2];set<pt>wzh;int n,tot;map<int,bool>nt[MAXN];double pt::y(){if(cl){return ::c[bel].y+sqrt(::c[bel].r*::c[bel].r-(X-::c[bel].x)*(X-::c[bel].x));}else{return ::c[bel].y-sqrt(::c[bel].r*::c[bel].r-(X-::c[bel].x)*(X-::c[bel].x));}}int main(){int i;scanf("%d",&n);for(i=1;i<=n;i++){scanf("%lf%lf%lf",&c[i].x,&c[i].y,&c[i].r);}for(i=1;i<=n;i++){e[++tot].x=c[i].x-c[i].r;e[tot].bel=i;e[tot].c=0;e[++tot].x=c[i].x+c[i].r;e[tot].bel=i;e[tot].c=1;}sort(e+1,e+tot+1);for(i=1;i<=tot;i++){X=e[i].x;if(e[i].c==0){set<pt>::iterator p=wzh.insert(pt(e[i].bel,0)).first;if(p!=wzh.begin()){p--;pt x=*p;p++;pt y=pt(e[i].bel,0);if(fabs((c[x.bel].x-c[y.bel].x)*(c[x.bel].x-c[y.bel].x)+(c[x.bel].y-c[y.bel].y)*(c[x.bel].y-c[y.bel].y)-(c[x.bel].r+c[y.bel].r)*(c[x.bel].r+c[y.bel].r))<eps){nt[x.bel][y.bel]=1;nt[y.bel][x.bel]=1;}}if(p!=(--wzh.end())){pt x=*(++p);pt y=pt(e[i].bel,0);if(fabs((c[x.bel].x-c[y.bel].x)*(c[x.bel].x-c[y.bel].x)+(c[x.bel].y-c[y.bel].y)*(c[x.bel].y-c[y.bel].y)-(c[x.bel].r+c[y.bel].r)*(c[x.bel].r+c[y.bel].r))<eps){nt[x.bel][y.bel]=1;nt[y.bel][x.bel]=1;}}wzh.insert(pt(e[i].bel,1));}if(e[i].c==1){wzh.erase(pt(e[i].bel,1));set<pt>::iterator p=wzh.find(pt(e[i].bel,0));if(p!=wzh.begin()&&(p!=--wzh.end())){pt x=*(--p);p++;pt y=*(++p);if(fabs((c[x.bel].x-c[y.bel].x)*(c[x.bel].x-c[y.bel].x)+(c[x.bel].y-c[y.bel].y)*(c[x.bel].y-c[y.bel].y)-(c[x.bel].r+c[y.bel].r)*(c[x.bel].r+c[y.bel].r))<eps){nt[x.bel][y.bel]=1;nt[y.bel][x.bel]=1;}}wzh.erase(pt(e[i].bel,0));}}int ans=0;for(i=1;i<=n;i++){ans+=nt[i].size();}printf("%d\n",ans/2);return 0;}/*70 0 12 0 14 0 16 0 10 2 10 4 10 6 1*/


0 0