【POI2011】【BZOJ2280】Plot
来源:互联网 发布:匈牙利命名法 数组 编辑:程序博客网 时间:2024/05/14 19:47
Description
给出一系列点p_1, p_2, … , p_n,将其分成不多余m个连续的段,第i段内求一个点q_i,使得q_i到这段内点的距离的最大值的最大值最小
Input
第一行,n m
下面n行,每行两个整数,表示p_i的x y坐标
1<=m<=n<=100000
坐标范围[-1000000,1000000]
Output
第一行,q_i到这段内点的距离的最大值的最大值的最小值
第二行,分成的段数k
下面k行,每行两个实数,表示q_k的x y坐标
All the real numbers should be printed with at most 15 digits after the decimal point.
Sample Input
7 2
2 0
0 4
4 4
4 2
8 2
11 3
14 2
Sample Output
3.00000000
2
2.00000000 1.76393202
11.00000000 1.99998199
HINT
wyx528提供SPJ
Source
二分一个半径,然后划分区间
划分时候倍增求区间长度否则T
我不知道求最小圆覆盖的时间复杂度是什么所以不会分析这题时间复杂度
但是从rank4-rank倒数做法都是一样的,时间差就在常数而已
但是我花160s A了这个题之后
有不知道哪里的傻逼偷了我的号密码
提交这个题又交了两发卡评测
#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#define eps 1e-10#define MAXN 100100using namespace std;int n,m,top,T=50;double R,l,r,mid;int ans[MAXN][2],cnt;struct Point{ double x,y;}s[MAXN],sta[MAXN],C;double sqr(double x){ return x*x;}double dis(Point a,Point b){ return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y));}Point Mid(Point a,Point b){ return (Point){(a.x+b.x)/2,(a.y+b.y)/2};}Point cen(Point a,Point b,Point c)//三点求圆心 { double x1=b.x-a.x,y1=b.y-a.y,x2=c.x-a.x,y2=c.y-a.y; double r1=(sqr(x1)+sqr(y1))/2,r2=(sqr(x2)+sqr(y2))/2,d=x1*y2-x2*y1; return (Point){a.x+(r1*y2-r2*y1)/d,a.y+(x1*r2-x2*r1)/d};}void calc(int l,int r)//对区间l,r的圆做最小圆覆盖 { top=0; for (int i=l;i<=r;i++) sta[++top]=s[i]; for (int i=1;i<=top;i++) swap(sta[rand()%i+1],sta[i]); C=sta[1];R=0; for (int i=1;i<=top;i++) { if (dis(C,sta[i])<=R+eps) continue; C=Mid(sta[1],sta[i]),R=dis(sta[i],C); for (int j=1;j<i;j++) { if (dis(C,sta[j])<=R+eps) continue; C=Mid(sta[i],sta[j]),R=dis(sta[i],C); for (int k=1;k<j;k++) if (dis(sta[k],C)>R+eps) C=cen(sta[i],sta[j],sta[k]),R=dis(sta[i],C); } }}bool check(double x)//确定划分的区间 { int cut=0,num=0,l,r,mid,j; for (int i=1;i<=n;i=cut+1) { for (j=1;i+(1<<j)-1<=n;j++) { calc(i,i+(1<<j)-1); if (R>x+eps) break; } cut=i;l=i+(1<<(j-1))-1;r=min(i+(1<<j)-1,n); while (l<=r) { mid=(l+r)>>1;calc(i,mid); if (R<x+eps) cut=mid,l=cut+1; else r=mid-1; } num++; if (num>m) return 0; } return 1;}void get_ans(double x){ int cut=0,l,r,mid,j; for (int i=1;i<=n;i=cut+1) { for (j=1;i+(1<<j)-1<=n;j++) { calc(i,i+(1<<j)-1); if (R>x+eps) break; } cut=i;l=i+(1<<(j-1))-1;r=min(i+(1<<j)-1,n); while (l<=r) { mid=(l+r)>>1;calc(i,mid); if (R<x+eps) cut=mid,l=cut+1; else r=mid-1; } ans[++cnt][0]=i;ans[cnt][1]=cut; } }int main(){ scanf("%d%d",&n,&m); for (int i=1;i<=n;i++) scanf("%lf%lf",&s[i].x,&s[i].y); calc(1,n); r=R; while (m>1&&r-l>eps&&T--) { mid=(l+r)/2; if (check(mid)) r=mid; else l=mid; } printf("%.9f\n",r); get_ans(r); printf("%d\n",cnt); for (int i=1;i<=cnt;i++) { calc(ans[i][0],ans[i][1]); printf("%.9f %.9f\n",C.x,C.y); }}
0 0
- 【POI2011】【BZOJ2280】Plot
- BZOJ2280: [Poi2011]Plot
- BZOJ 2280 Poi2011 Plot 二分答案+随机增量法
- [二分答案 随机增量法] BZOJ 2280 [Poi2011]Plot
- plot
- 【POI2011】 Meteors
- POI2011 题解
- [bzoj 2526]Poi2011 Inspection
- [bzoj 2525]Poi2011 Dynamite
- [BZOJ 2277]Poi2011 Strongbox
- 【BZOJ 2527】 [Poi2011]Meteors
- BZOJ 2529 Poi2011 Sticks
- BZOJ 2217 Poi2011 Lollipop
- 【POI2011】【BZOJ2527】Meteors
- bzoj2276【poi2011】Temperature
- BZOJ2527: [Poi2011]Meteors
- 2527: [Poi2011]Meteors
- bzoj2215: [Poi2011]Conspiracy
- WebViewClient与WebChromeClient的区别
- JS Date 格式化时间
- 策略模式
- spring管理属性配置文件properties——使用PropertiesFactoryBean
- poj1258
- 【POI2011】【BZOJ2280】Plot
- 数据库隔离级别
- Android AsyncTask两种线程池分析和总结
- hdu 1323 Perfection
- 确定两串乱序同构(程序员面试金典)
- spring实现javaMail
- C++在控制台上实现2048游戏
- iOS开发:图片的异步加载
- AdapterViewFliper 的用法