HDU 5531 Rebuild (三分) ★ ★
来源:互联网 发布:js手机脚本大全 编辑:程序博客网 时间:2024/05/16 07:26
题目大意:给定一个凸N边形N个顶点坐标(N>=3),在N边形每个顶点上构造一个圆要求相邻两顶点的圆相切,求能构造出的最小总圆面积
数据范围: 3 <= N <= 10000, 3 <= xi , yi <= 10000
题目解答:三分法求下凸函数(复杂度O(N*log3(N)))
假设第一个点构造的圆半径为r,则其他点构造出的圆的半径可以依次表示出来,最后的答案是关于r的一个二次函数。
对于N边形分奇偶讨论:
- N为奇数:此时关于r的二次函数没有r的一次项,则最终面积结果可以直接求解
- N为偶数:此时关于r的二次函数有r的一次项,是一个下凸函数,想到三分求解
注意:三分的时候边界条件处理不好可能会导致WA,注意对最后二分出的结果取(l+r)/ 2作为答案
#include <set>#include <map>#include <stack>#include <queue>#include <deque>#include <cmath>#include <vector>#include <string>#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>using namespace std;#define L(i) i<<1#define R(i) i<<1|1#define INF 0x3f3f3f3f#define pi acos(-1.0)#define eps 1e-9#define maxn 100100#define MOD 1000000007int n;double dis[maxn],Ra[maxn];double x[maxn],y[maxn];double ans;double get_dis(int i,int j){ return sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));}int solve(double r){ double tmp = -r; for(int i = 0; i < n; i++) { tmp = dis[i] - tmp; Ra[i] = tmp; if(tmp < 0) return 0; } ans = 0; for(int i = 0; i < n; i++) ans += Ra[i] * Ra[i]; ans *= pi; return 1;}int main(){ int t,C = 1; scanf("%d",&t); while(t--) { scanf("%d",&n); dis[0] = 0; for(int i = 0; i < n; i++) { scanf("%lf%lf",&x[i],&y[i]); if(i) dis[i] = get_dis(i,i-1); if(i == n-1) dis[n] = get_dis(i,0); } double L = 0,R = dis[1]; double sum = 0; for(int i = 1; i <= n; i++) { sum = dis[i] - sum; if(i & 1) R = min(R,sum); else L = max(L,-sum); } if(n & 1) { double r = sum / 2; if(!solve(r) || r < 0) printf("IMPOSSIBLE\n"); else { printf("%.2f\n",ans); for(int i = 0; i < n; i++) printf("%.2f\n",Ra[i]); } } else { if(L > R || fabs(sum) > eps) { printf("IMPOSSIBLE\n"); continue; } double l = L,r = R; while(l + eps < r) { double mid = l + (r - l) / 3; double mmid = r - (r - l) / 3; solve(mid); double ans1 = ans; solve(mmid); double ans2 = ans; if(ans1 < ans2) r = mmid; else l = mid; } solve(l); printf("%.2f\n",ans); for(int i = 0; i < n; i++) printf("%.2f\n",Ra[i]); } } return 0;}
0 0
- HDU 5531 Rebuild (三分) ★ ★
- hdu 5531 Rebuild(三分)
- hdu 5531 Rebuild(三分)
- hdu 5531 Rebuild 三分
- HDU 5531(Rebuild- 三分)
- HDU 5531 Rebuild(三分)
- HDU 5531 Rebuild(三分)——2015ACM/ICPC亚洲区长春站
- HDU 5531 Rebuild 题解
- HDU 5531 Rebuild(几何)
- HDU 5531 (平面几何 三分)
- HDU 5531 (ACM 2015 长春) Rebuild [计算几何]
- HDU 5531(2015长春 icpc E.Rebuild) 计算几何
- hdu 4454(三分)
- HDU 5531 Rebuild 相切的圆们
- HDU 3400(搜索题,三分~~初识三分查找)
- hdu 3400 Line belt(三分套三分)
- HDU 3400 Line belt (三分套三分)
- [HDU]5531 Rebuild (三分法求下凸函数,维护最小圆面积)
- poj 1321 — 棋盘问题(简单DFS)
- 【Day15】posix和perl标准的正则表达式区别?
- java中的排序类用法
- ubuntu安装中文输入法fcitx框架
- java集合遍历
- HDU 5531 Rebuild (三分) ★ ★
- Android开发——View绘制过程源码解析(二)
- 博客编辑上传图片时出现 C:\fakepath\文件路径问题
- 求一元二次方程解
- 8086寻址方式
- nmap系列之mysql
- windows上xgboost 安装及问题
- 全志a20修改设备基本信息--> 修改 build.prop
- c++ char in short long double占字节数