http://acm.hdu.edu.cn/showproblem.php?pid=4752

数学题,题目大意是给一条抛物线,然后还定义域,再给n个点,从第i个点连接到第(i+1)个点,然后最后一个点和第一个点连接,最后构成一个n边形,然后要求的是抛物线落在n边形里面的弧长长度的总和。
本来是想一段一段求出来的,可是想了半天都没想出要怎么做出来,后来看了别人的代码,才发现原来是用 多还少补 的思想。
思路大概是这样的:
先考虑第 i 和 (i-1) 个点构成的线段是否垂直于x轴,如果垂直,则这条线是用于辅助将多边形包围进去,无需计算,如果不是,就开始求交点,交点可能有一个也有可能有两个,或者没有,有交点的情况,可以直接当初有两个交点来考虑,然后就可以把一条线段分成三段。计算的时候,要分成一段一段的线段来求,先不考虑是否多加的情况,只要抛物线在线段下方,由线段端点或者原来抛物线的定义域来确定左右区间,然后计算的话,就是定积分的问题了,套套公式就可以了,如果上一条线段是垂直于x轴,且端点正好在抛物线上,这种情况也还是可以算的,不会漏掉。然后这样肯定是会多算的,所以我们得把多算的扣掉,然后就是通过规定方向来将多余的扣掉的,方向随便规定,我这边规定的是从右往左是正方向,这样如果我们多加了,因为要最后要首尾相连,肯定有一些算出来是反方向的,正好可以把多算的抵消掉。然后如果是没有交点的,只需要考虑线段是否在抛物线的上方,如果在,只有两种情况,一种是因为前面有一条垂直于x轴的线段,或者抛物线定义域的限制,直接计算一下就可以了。最后还有一点需要注意,因为是有规定方向的,然后将点给的顺序颠倒一下,得到的结果就是原来的相反数了,所以最后的结果别忘了取个绝对值。

#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;const int maxn = 20005;typedef struct POINT
{int x;int y;
}Point;int n;
Point point[maxn];
long double a, b, c, L, R;inline long double sqr(long double x)
{return x * x;
}//用于计算定积分
long double f(long double x)
{long double temp = sqrt( sqr(b + 2*a*x) + 1 );return ( (b + 2*a*x)*temp + log(b + 2*a*x + temp) ) / (a*4);
}//计算两点之间的抛物线的长度
long double calc( long double x0, long double y0, long double x1, long double y1 )
{    //如果抛物线位于这条线段上方,易知不用计算double xx = (x0 + x1) / 2;if ( a * xx * xx + b * xx + c > (y0 + y1) / 2 )return 0;//更新左右端点//如果只有一个交点,这边显然算出来是0。long double l = max( L, x0 );long double r = min( R, x1 );return l < r ? f(r) - f(l) : 0;
}int main()
{//固定的浮点数显示cout << fixed;//设置精度为小数点后两位cout.precision(2);while (cin >> n){cin >> a >> b >> c >> L >> R;for (int i = 1; i <= n; i++ ) scanf( "%d%d", &point[i].x, &point[i].y );point[0].x = point[n].x;point[0].y = point[n].y;long double ans = 0;for ( int i = 1; i <= n; i++ )//要计算抛物线在多边形里面的长度,线段肯定不能是垂直于x轴,//就算是与抛物线有交点,也只是辅助将抛物线包围进去if ( point[i].x != point[i-1].x ){long double x0 = point[i-1].x, y0 = point[i-1].y;long double x1 = point[i].x, y1 = point[i].y;long double k = ( y1 - y0) / ( x1 - x0 );long double d = y0 - k * x0;long double dat = sqr(b - k) - 4 * a * (c - d);long double length = 0;//确保 x0 在 x1 左边if ( x0 > x1 )        {swap( x0, x1 );swap( y0, y1 );}if ( dat >= 0 ){long double x2 = ( -(b - k) + sqrt(dat) ) / (2 * a);long double x3 = ( -(b - k) - sqrt(dat) ) / (2 * a);//确保 x2,x3 落在 x0 与 x1 之间,并且 x2 在 x3 左边if ( x2 < x0 )x2 = x0;if ( x2 > x1 )x2 = x1;if ( x3 < x0 )x3 = x0;if ( x3 > x1 )x3 = x1;if ( x2 > x3 )swap(x2, x3);long double y2 = k * x2 + d, y3 = k * x3 + d;length += calc( x0, y0, x2, y2 );length += calc( x2, y2, x3, y3 );length += calc( x3, y3, x1, y1 );}//如果没有交点的话,只需要考虑抛物线是否在这个线段的上方即可//如果线段在上方的话,因为抛物线本来的定义域的限制,//或者前一条线段是垂直于x轴的,所以还是要计算的elselength += calc( x0, y0, x1, y1 );//因为这种求法是一段一段考虑的,然后肯定会多加了,或者多减了,//所以得考虑好方向,然后相应地减掉或者是加上原来多了或者是少了的抛//物线的长度,最后从最后一个点连到第一个点才能正好算出抛物线的长度if ( point[i-1].x < point[i].x )ans -= length;elseans += length;}//这种思路,如果把点给的顺序颠倒过来的话,求出来的ans是//原来求的ans的相反数,所以得取个绝对值。cout << abs(ans) << endl;}return 0;
}

View Code

转载于:https://www.cnblogs.com/tank39/p/3911411.html

HDU 4752 Polygon相关推荐

  1. HDU 4752 Polygon(抛物线长度积分)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4752 题意:给出一个抛物线和一个简单多边形.求抛物线在多边形内部的长度. 思路:首先求出多边形所有边和 ...

  2. 2013_nanjing_online

    4748 Area 4749 Parade Show 贪心+模式匹配/rk-hash 4750 Count The Pairs 最小瓶颈生成树,统计瓶颈>=c的个数. 4751 Divide G ...

  3. HDU 4033 Regular Polygon(二分+高精度)

    比赛时没做出来,最后10 钟时倒是想枚举每个角度,精度估计上可能会出问题: 后来听"理宝"说可以暴力枚举边的长度,精确到0.001,数据恰好10^7,T_T~~ vongang说可 ...

  4. [2019HDU多校第一场][HDU 6590][M. Code]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6590 题目大意(来自队友):二维平面上有\(n\)个点,每个点要么是黑色要么是白色,问能否找到一条直线 ...

  5. H - Square Card HDU - 7063

    H - Square Card HDU - 7063 题意: 有两个圆形区域,一个是得分区域,一个是获得奖金区域,现在你有一个边长为a的正方形,当正方形在如果在某一时刻它严格在圆形范围内,才算合法. ...

  6. HDU题目分类大全【大集合】

    基础题: 1000.1001.1004.1005.1008.1012.1013.1014.1017.1019.1021.1028.1029.  1032.1037.1040.1048.1056.105 ...

  7. [2019HDU多校第四场][HDU 6617][D. Enveloping Convex]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6617 题目大意:给出一凸包\(P\),求最小的与\(P\)相似且对应边平行的多边形,使得题目给出的\( ...

  8. 转载:Hdu 题目分类

    原址点击 基础题:1000.1001.1004.1005.1008.1012.1013.1014.1017.1019.1021.1028.1029. 1032.1037.1040.1048.1056. ...

  9. hdu 1506 Largest Rectangle in a Histogram 最大矩形

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1506 Largest Rectangle in a Histogram Time Limit: 20 ...

最新文章

  1. python变量必须以字母和下划线_【转载】关于python中带下划线的变量和函数的意义...
  2. Android自定义波浪加载圆形进度条——(自定义控件 一)
  3. RosBE生成ReactOS的VS2015工程失败2
  4. HTTP Status 405 - JSPs only permit GET POST or HEAD问题的分析和解决办法
  5. ASP.NET CORE 项目实战 ---图形验证码的实现
  6. 在CentOS上安装NodeJS_v14.x
  7. 带你掌握不同平台下,探索JDK源码所需的native方法
  8. 这可能是迄今为止对大前端最好的解释
  9. 早晨有好多学生在买早餐吃,这样好吗?家长不给孩子做饭吗?
  10. Python中的分组函数(groupby、itertools)
  11. document.readyState 属性
  12. iOS开发之国际化(本地化)
  13. Photoshop抠图--使用图层蒙版抠图
  14. 人在囧途——Java程序猿学习Python
  15. vuex报错TypeError: sub is not a function
  16. 红色建筑装饰公司营销型网站织梦模板
  17. shell 脚本实战 五
  18. Python使用Plotly绘图工具,绘制散点图、线形图
  19. ZOU YI BU
  20. 吕雉到底是一个怎样的人?

热门文章

  1. 小米计算机无法清除,小米电脑清空回收站找回【完整解决方案步骤】
  2. Imagemagick中图片大小转换全攻略
  3. 常微分方程(ode)一步法的求解(python) (龙格库塔法(Runge-Kutta))
  4. BroadCast的两种使用方法
  5. ubuntu nvidia显卡驱动failed解决方法
  6. 经典SQL题练习(MySQL版)
  7. 我的世界java版月步教程,【我的世界】我的世界三大极限操作展现!完美月步艳惊四座 无道具瞬移实现_玩得好游戏攻略...
  8. 泊松分酒--蓝桥杯java历年真题
  9. 对青藏高原进行MK趋势分析
  10. 快速了解什么是HotSpot