#include<stdio.h> #include<string.h> #include<ctype.h> #include<math.h> #include<iostream> #include<string> #include<set> #include<map> #include<vector> #include<queue> #include<bitset> #include<algorithm> #include<time.h> using namespace std; void fre(){freopen("c://test//input.in","r",stdin);freopen("c://test//output.out","w",stdout);} #define MS(x,y) memset(x,y,sizeof(x)) #define MC(x,y) memcpy(x,y,sizeof(x)) #define MP(x,y) make_pair(x,y) #define ls o<<1 #define rs o<<1|1 typedef long long LL; typedef unsigned long long UL; typedef unsigned int UI; template <class T1,class T2>inline void gmax(T1 &a,T2 b){if(b>a)a=b;} template <class T1,class T2>inline void gmin(T1 &a,T2 b){if(b<a)a=b;} const int N=2e5+10,M=0,Z=1e9+7,ms63=1061109567; const double PI=acos(-1.0); int casenum,casei; int n; int x[N],h[N]; int s[N],top; double ans[N]; double angle(int p1,int p2) { return atan(fabs(1.0*(h[p1]-h[p2])/(x[p1]-x[p2]))); } int main() { while(~scanf("%d",&n)) { for(int i=1;i<=n;i++)scanf("%d%d",&x[i],&h[i]); top=0; for(int i=1;i<=n;i++) { while(top&&h[s[top]]<=h[i])--top; while(top>1&&angle(i,s[top-1])>angle(i,s[top]))--top; ans[i]=top?angle(i,s[top]):0; s[++top]=i; } top=0; for(int i=n;i>=1;i--) { while(top&&h[s[top]]<=h[i])--top; while(top>1&&angle(i,s[top-1])>angle(i,s[top]))--top; ans[i]+=top?angle(i,s[top]):0; s[++top]=i; } for(int i=1;i<=n;i++)printf("%.16f\n",(1-ans[i]/PI)*12); } return 0; } /* 【trick&&吐槽】 凸包思维是很常见的哦 【题意】 有n(2e5)座建筑物,我们认为每个建筑物的宽度都为0。 现在从西向东,告诉你每个建筑物的坐标和高度。 让你对于每个建筑物,输出其顶部被阳光照射的时间。 【类型】 栈 【分析】 这道题和我们的生活很有关联2333。 如果无遮挡,日照时间最大为12小时, 否则遮挡可能来自于西面,也可能来自于东面。 我们把两侧的遮挡时间算一下,用12减一下。 或者一侧的光照时间按照最大6小时来算,两侧加起来即可。 然而固定方向后,我们该如何求遮挡时间呢? 我们作图或者结合生活,发现我们,就算使得太阳从0°转到90°。 其实对一个楼的光照产生遮挡的楼层也只会是另外的唯一一个。 这对应的其实是最大遮挡角。 至于它的求法,我们可以暴力枚举在它之前的所有楼,算出一个最大值。 然而这个复杂度是O(n^2),我们就要爆炸啦。 那么用什么方法求比较好呢? 没错,就是用栈时限 这个其实类似于凸包的形式。 我们可以用栈的方式处理这个关系。 如果它的高度比栈顶的高,那么我们就一直退栈。 如果它的高度没栈顶的高,那么栈顶的都可能对其产生遮挡。 我们查看栈最上方的两个建筑物对它的遮挡角的大小, 1,如果栈顶的遮挡角<=次栈顶的遮挡角,那么我们肯定退栈。 因为当前栈顶元素对于遮挡而言永远没有次栈顶的优。 2,如果栈顶的遮挡角>次栈顶的遮挡角。那么当前栈顶元素就是所有点中,对当前点的遮挡性最强的。 因为栈中的点,连起来其实会形成一个恰好的凸包,所以这个结论很明显。 于是我们两个方向都扫描一下,就能得到答案。 【时间复杂度&&优化】 O(n) 【数据】 input 4 1 1 2 2 3 2 4 1 output 9.0000 12 12.00000 9.0 input 5 100 50 125 75 150 100 175 125 200 25 output 9.0 9.0 9.0 12.0 6.9357496 */