这个题和下个题都是那个台湾某大学网站上扫描线分类的。
当然我这个题没感觉我那是扫描线过的,觉得是枚举过去的。。
这题给你N个点,代表山峰和山谷,然后问你阳光能照到的长度。
这题简化了,一个山峰必然挨着一个山谷。但是第一个点不一定是山峰,需要判断。
然后直接找某个山峰后面的最高点,如果最高点比山峰高,那么说明这个山峰的向阳侧肯定要被遮盖掉,就不计算了,如果低的话,求交点后计算长度即可。
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <math.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <limits.h>
#include <string.h>
#include <string>
#include <algorithm>
#define MID(x,y) ( ( x + y ) >> 1 )
#define L(x) ( x << 1 )
#define R(x) ( x << 1 | 1 )
#define BUG puts("here!!!")
#define STOP system("pause")
using namespace std;
const int MAX = 110;
struct point{ double x,y; bool peak;};
point p[MAX];
const double eps = 1e-6;
bool dy(double x,double y) { return x > y + eps;} // x > y
bool xy(double x,double y) { return x < y - eps;} // x < y
bool dyd(double x,double y) { return x > y - eps;} // x >= y
bool xyd(double x,double y) { return x < y + eps;} // x <= y
bool dd(double x,double y) { return fabs( x - y ) < eps;} // x == y
double disp2p(point a,point b) // a b 两点之间的距离
{
return sqrt( ( a.x - b.x ) * ( a.x - b.x ) + ( a.y - b.y ) * ( a.y - b.y ) );
}
bool cmp(point a,point b)
{
return a.x < b.x;
}
point l2l_inst_p(point u1,point u2,point v1,point v2)
{
point ans = u1;
double t = ((u1.x - v1.x)*(v1.y - v2.y) - (u1.y - v1.y)*(v1.x - v2.x))/
((u1.x - u2.x)*(v1.y - v2.y) - (u1.y - u2.y)*(v1.x - v2.x));
ans.x += (u2.x - u1.x)*t;
ans.y += (u2.y - u1.y)*t;
return ans;
}
int main()
{
int ncases, n;
scanf("%d", &ncases);
while( ncases-- )
{
scanf("%d",&n);
for(int i=0; i<n; i++)
{
scanf("%lf%lf", &p[i].x, &p[i].y);
p[i].peak = false;
}
sort(p, p+n, cmp);
int i = 0;
if( p[0].y < p[1].y ) //如果第一个点是山谷,那么第二个点一定是山顶
i = 1;
for(; i<n; i+=2)
p[i].peak = true; //标记山顶的点
double len = 0.0;
for(int i=0; i<n; i++)
{
if( p[i].peak )
{
double high = 0.0;
for(int k=i+2; k<n; k++)
if( dy(p[k].y, high) )
high = p[k].y;
if( dyd( high,p[i].y) )
continue;
point t; t.x = -1; t.y = high;
point tt = t; tt.x = -2;
point c = l2l_inst_p(tt, t, p[i], p[i+1]);
len += disp2p(c, p[i]);
}
}
printf("%.2lf\n",len);
}
return 0;
}