HDU 5531 几何公式
来源:互联网 发布:华讯网络好吗 编辑:程序博客网 时间:2024/05/29 15:08
#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>using namespace std;const int maxn = 1e4 + 5;const double INF = 1e20;const double PI = acos(-1);const double eps = 1e-8;struct Point{ double x, y; Point(double x = 0, double y = 0): x(x), y(y) {}};int dcmp(double x)//{ if (fabs(x) < eps) return 0; else return x < 0 ? -1 : 1;}double Distance(Point A, Point B){ return sqrt((A.x - B.x) * (A.x - B.x) + (A.y - B.y) * (A.y - B.y));}double Distance2(Point A, Point B){ return (A.x - B.x) * (A.x - B.x) + (A.y - B.y) * (A.y - B.y);}Point read_point(){ double X, Y; scanf("%lf%lf", &X, &Y); return Point(X, Y);}Point P[maxn];int n, T;double L, R, A[maxn], Dis[maxn];double get(double m){ double ret = m * m; A[0] = m; for (int i = 1; i < n; i++) { m = Dis[i - 1] - m; ret += m * m; A[i] = m; } return ret;}double solve (){ while (R - L > eps) { double l = (2 * L + R) / 3; double r = (L + 2 * R) / 3; if (get(l) >= get(r)) L = l; else R = r; } return L;}int main(int argc, char const *argv[]){ scanf("%d", &T); while (T--) { scanf("%d", &n); for (int i = 0; i < n; i++) P[i] = read_point(); P[n] = P[0]; double s = 0, ans = 0; L = 0, R = INF; for (int i = 0; i < n; i++) { Dis[i] = Distance(P[i], P[i + 1]); s = Dis[i] - s; ans = Dis[i] - ans; if (i & 1) L = max(L, -s); else R = min(R, s); } if ((L > R) || (n % 2 == 0 && dcmp(ans) != 0)) printf("IMPOSSIBLE\n"); else { if (n & 1) ans /= 2; else ans = solve(); printf("%.2lf\n", get(ans) * PI); for (int i = 0; i < n; i++) printf("%.2lf\n", A[i]); } } return 0;}
没有想出做法,看了题解。
题意:按顺序给出一个多边形,以多边形的每个顶点为圆心作圆,使得任意两相邻点对应的圆相切,求所有圆面积总和的最小值。
画个图算两下就出来了,发现只需要对n的奇偶性进行讨论即可。
设每个点为pi(0 <= i <= n - 1),对应圆的半径为ri,pi和p(i + 1)(默认pn为p0)的距离为di,则很显然我们得到了n个方程:
Fi:ri + r(i + 1) = di(0 <= i <= n - 1)。
通过这个方程我们发现,全部加起来除以2即得到了所有ri的和。当n为奇数时,将i为奇数的方程Fi相加可以得到r1 + r2 + ...... + r(n - 1)的和,再用总和减去它即得到了r0,也就是说,n为奇数时,这个方程组有唯一解,所以,解出所有的解,只要所有解都非负即可算出答案,如果有负的就IMPOSSIBLE。当n为偶数时,i为偶数的方程相加和i为奇数的方程相加的结果应该是一样的(都等于所有ri之和)。所以先算这两个和,如果这两个和不相等,也是IMPOSSIBLE。其次,我们从第二个方程起,可以将每个ri都变成与r0相关的式子,这样,所有圆的面积都可以用r0表示,最后的总面积是关于r0的二次函数,直接求解最小值即可。设ri = ai*r0 + bi,
则r(i + 1) = di - ri = -ai*r0 - bi + di。所以a(i + 1) = -ai,b(i + 1) = - bi + di。a0 = 1,b0 = 0。这样求出每个ai和bi(可以发现ai只有1和-1),然后面积和 = pi*sigma(ri^2,0 <= i <= n - 1) = A*r0^2 + B*r0 + C,算出A,B,C的值再根据每个ri的范围(0 <= ri <= min(di,d(i + 1))求出r0的取值范围(即维护区间的左右端点),如果区间右端点小于左端点,则无解IMPOSSIBLE。否则根据二次函数性质算出区间内最低点即可。
题解来自:http://blog.csdn.net/firstlucker/article/details/49557517
- HDU 5531 几何公式
- (HDU 5733) tetrahedron <几何公式>
- hdu 5448 Marisa’s Cake(计算几何加推公式)
- HDU 4386(计算几何+婆罗摩笈多公式一般形式)
- HDU 5531 Rebuild(几何)
- 计算几何求公式
- 几何公式总结
- 计算几何相关公式
- 计算几何公式
- 计算几何公式总结
- 常用的几何公式
- 公式/几何曲线图片
- hdu 5733 tetrahedron(2016 Multi-University Training Contest 1——几何公式题)
- HDU 4798 Skycity (计算几何+推公式) 2013 Asia Changsha Regional Contest
- POJ 1265 Area 几何公式
- 基础几何知识及公式
- [计算几何]几何图形及计算公式查询
- 【计算几何】【simpson自适应公式】【NOI2009】描边
- 九度题目1104整除问题
- B-树和B+树的应用:数据搜索和数据库索引
- dfs和bfs
- window环境下安装easy_install
- Linux Select/Epoll注记
- HDU 5531 几何公式
- Firefox 与 sublime text 3 通过LiveReload插件实现前端代码实时预览
- flask 实现上传图片并缩放作为头像
- POJ 1930 Dead Fraction(小数化分数)
- 【USACO5.3.3】Network of Schools
- Spark+Kafka的Direct方式将偏移量发送到Zookeeper的实现
- python标准库学习3-fileinput
- B树、B-树、B+树、B*树 红黑树
- OpenLayers 3 之 事件体系详解