HDU 5033 Building (2014年北京赛区网络赛B题)
2015-09-04 22:47
435 查看
1.题目描述:点击打开链接
2.解题思路:本题利用单调栈解决。第一次做这个题用的在线处理,找左边和右边的极大值点,最后总是WA,然后才恍然大悟自己的方法错了,因为可能中间是一些低的楼,后面突然出现一个非常高的楼。因此一下子意识到本题要用单调栈来解决。
如果用单调栈解决,需要进行离线处理,把询问也当做坐标考虑进去,然后从左往右扫描,使栈中的结点构成的曲线呈现一种下降的,而且是上凸的样子,这样,栈顶元素就是我们要找的点,然后计算它和目标点之间和y轴的夹角。扫描完后,把整个数组翻转,但x值还要呈现从小到大的趋势(即只是把h值翻转了),然后再从左往右扫描一遍,最后累加和y轴的夹角,这样只需要O(N+Q)时间即可算出所有的答案。
3.代码:
2.解题思路:本题利用单调栈解决。第一次做这个题用的在线处理,找左边和右边的极大值点,最后总是WA,然后才恍然大悟自己的方法错了,因为可能中间是一些低的楼,后面突然出现一个非常高的楼。因此一下子意识到本题要用单调栈来解决。
如果用单调栈解决,需要进行离线处理,把询问也当做坐标考虑进去,然后从左往右扫描,使栈中的结点构成的曲线呈现一种下降的,而且是上凸的样子,这样,栈顶元素就是我们要找的点,然后计算它和目标点之间和y轴的夹角。扫描完后,把整个数组翻转,但x值还要呈现从小到大的趋势(即只是把h值翻转了),然后再从左往右扫描一遍,最后累加和y轴的夹角,这样只需要O(N+Q)时间即可算出所有的答案。
3.代码:
#include<iostream> #include<algorithm> #include<cassert> #include<string> #include<sstream> #include<set> #include<bitset> #include<vector> #include<stack> #include<map> #include<queue> #include<deque> #include<cstdlib> #include<cstdio> #include<cstring> #include<cmath> #include<ctime> #include<cctype> #include<complex> #include<functional> #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; #define me(s) memset(s,0,sizeof(s)) #define rep(i,n) for(int i=0;i<(n);i++) typedef long long ll; typedef unsigned int uint; typedef unsigned long long ull; typedef pair <int, int> P; const int N=200100; const int INF=100000000; const double PI=acos(-1.0); struct Node { int x,h; bool operator<(const Node&a)const { return x<a.x; } }; Node p ,st ; double ans ; int n,q; int check(Node a,Node b,Node c) { if(c.h<=0)c.h=0; return (ll)(a.h-c.h)*(c.x-b.x)>=(ll)(b.h-c.h)*(c.x-a.x); } double Angle(Node a,Node b) { return atan(1.0*(b.x-a.x)/a.h); } void solve() { int top=0; for(int i=0;i<n+q;i++) { if(p[i].h<=0)//如果是询问的点 { while(top>=2&&check(st[top-2],st[top-1],p[i]))top--; //如果曲线呈现向下凸的趋势,出栈 ans[-p[i].h]+=Angle(st[top-1],p[i]);//-p[i].h就是询问的下标 } else { while(top&&st[top-1].h<=p[i].h)top--; //如果y值呈现递增趋势,出栈 while(top>=2&&check(st[top-2],st[top-1],p[i]))top--; //如果曲线呈现向下凸的趋势,出栈 st[top++]=p[i]; //入栈 } } } int main() { int T; scanf("%d",&T); for(int kase=1;kase<=T;kase++) { scanf("%d",&n); for(int i=0;i<n;i++) scanf("%d%d",&p[i].x,&p[i].h); scanf("%d",&q); for(int i=0;i<q;i++) { scanf("%d",&p[i+n].x); p[i+n].h=-i; //用-i来标记询问的结点 } me(ans); sort(p,p+n+q); solve(); reverse(p,p+n+q); //翻转 for(int i=0;i<n+q;i++) p[i].x=INF-p[i].x; //x仍然变为递增趋势 solve(); printf("Case #%d:\n",kase); for(int i=0;i<q;i++) printf("%.10lf\n",ans[i]/PI*180); } }
相关文章推荐
- 椰角网络运营的TuziCMS企业网站管理系统正式上线
- TCP的三次握手(建立连接)和四次挥手(关闭连接)
- Linux分享之iptables:防火墙以及网络协议基本原理
- iOS安全系列之一:HTTPS
- http使用post和get方式提交数据
- OSI七层模型与TCP/IP四层模型
- ios网络:应用一个请求的7个步骤
- Caffe学习:使用pycaffe进行网络训练与测试
- 监听所有rtp/rtcp包
- nginx访问控制allow、deny(ngx_http_access_module)
- Stanford机器学习---第五讲. 神经网络的学习 Neural Networks learning
- Caffe学习:使用pycaffe定义网络
- 深入理解HTTP Session
- Stanford机器学习---第四讲. 神经网络的表示 Neural Networks representation
- 前向型神经网络之BPNN(附源码)
- hdu 3127 WHU girls 2009武汉网络赛 dp
- 机器学习之深度学习(Deep Learning)
- TCP: time wait bucket table overflow
- 机器学习之基于3D卷积神经网络的人体行为理解(论文笔记)
- backtrack5R3之基础网络常见命令