博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HDOJ 4368
阅读量:4226 次
发布时间:2019-05-26

本文共 2647 字,大约阅读时间需要 8 分钟。

题意:给一个山脉,高低起伏,问向某一个方向旋转一个角度后(角度绝对值属于[0.0,80.0]),所能盛水的容量。

题解:向右转还是向左转差别不大,只需要将山脉reverse就行了。现在考虑向右转,从左往右遍历顶点,以该顶点(设为i)为起始点向右发出一条水平射线,与山脉某一条边碰撞(记为j),在这射线之下所能盛水的面积就等于射线与山脉所组成梯形减去这期间山脉的面积。但还要从记录的这条边的顶点处往左发出一条射线,与山脉某条边k碰撞,这条新射线会与原射线形成一个小梯形(也可能是平行四边形),这部分区域没有计算,所以还应加上。另外,遍历结点的指针就可以直接跳转到j了,因为i到j的区域面积已经计算完了。如此,遍历一遍就可以得出结果。

PS: 打代码速度还是慢了些,最后提交是17:00:37秒,out of contest time 囧,结果赛下一交成为第一个A的,坑爹啊。

#include
#include
#include
#include
using namespace std;#define sign(x) ((x)>eps?1:((x)<-eps?(-1):(0))) //符号函数const double eps=1e-8;const double PI=acos(-1.0);const double inf=1e20;int n;struct point{ double x,y; point(){} point(double _x,double _y){x=_x,y=_y;}};struct seg{ point a,b; seg(){} seg(point _a,point _b){a=_a,b=_b;}};point L,R,po[20010];seg so[20010];inline double dist(point a,point b){ return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}void counter (double &x,double &y,double th){//绕原点逆时针旋转th弧度,顺时针则传入-th double tx=x,ty=y; x=tx*cos(th)-ty*sin(th); y=tx*sin(th)+ty*cos(th); return;}point R_rotata(point p,double ang){ point q; ang=ang*PI/180.0; q.x=p.x-R.x;q.y=p.y; counter(q.x,q.y,ang); q.x+=R.x; return q;}double xmult(double x1,double y1,double x2,double y2){ return x1*y2-x2*y1;}point line_intersection(seg u,seg v){ double a1=u.b.y-u.a.y,b1=u.a.x-u.b.x; double c1=u.b.y*(-b1)-u.b.x*a1; double a2=v.b.y-v.a.y,b2=v.a.x-v.b.x; double c2=v.b.y*(-b2)-v.b.x*a2; double D=xmult(a1,b1,a2,b2); return point(xmult(b1,c1,b2,c2)/D,xmult(c1,a1,c2,a2)/D);}int findleft(point p,int k,point &q){ int i; for(i=k;i>=0;i--) { if(so[i].b.y>p.y-eps) break; } if(i<0) return i; else if(i%2==1) { q=line_intersection(seg(p,point(p.x-1.0,p.y)),so[i]); return i;//与右边相遇 } else { q=line_intersection(seg(p,point(p.x-1.0,p.y)),seg(so[i].b,so[i+1].b)); return i;//与头顶相遇 }}int findright(point p,int k,point &q){ int i; for(i=k;i
p.y-eps) break; } if(i>=n) return i; else { q=line_intersection(seg(p,point(p.x+1.0,p.y)),so[i]); return i; }}double h[10010];int main(){ int num; double angle; while(scanf("%d%lf",&num,&angle)!=EOF) { n=num*2; R.x=(double)num,R.y=0; for(int i=0;i
eps) { reverse(h,h+num); angle=-angle; } for(int i=0;i
=n) { i++; continue; } ans=ans+(dist(so[i].a,so[i].b)+dist(so[j].a,q1))*(po[j].x-po[i].x)/2.0; if(i&1) for(tp=i+1;tp
=n) { i+=2; continue; } ans=ans+(dist(so[i].a,so[i].b)+dist(so[j].a,q1))*(po[j].x-po[i].x)/2.0; for(tp=i+1;tp

转载地址:http://oxbqi.baihongyu.com/

你可能感兴趣的文章
在Ubuntu上下载、编译和安装Android最新内核源代码(Linux Kernel
查看>>
Linux内核同步机制API函数:宏:spin_lock_init ( )
查看>>
driver_register 理解
查看>>
copy_from_user && copy_to_user
查看>>
device_register
查看>>
Android上C++对象的自动回收机制分析
查看>>
从spin_lock到spin_lock_irqsave
查看>>
sdio 驱动
查看>>
vim 常用用法
查看>>
更好就足够了吗?| 驱动变革
查看>>
技术选型指南
查看>>
在一家技术公司做媒体
查看>>
项目管理的三个关键
查看>>
从技术雷达看DevOps十年-DevOps和持续交付
查看>>
从架构可视化入门到抽象坏味道
查看>>
重读领域驱动设计——如何说好一门通用语言
查看>>
不就是个短信登录API嘛,有这么复杂吗?
查看>>
第二十期技术雷达正式发布——给你有态度的技术解析
查看>>
从技术雷达看DevOps的十年 – 基础设施即代码和云计算
查看>>
Scala 3 不再支持 XML 了吗?
查看>>