hdoj 1687 Lucky Light 【区间找点】

思路:将所有的线段的两端坐标利用两点式(其中一个点是光源点另一个点是线段的端点)都投影到x坐标轴上, 在利用区间找点找出空白处即可;

需要注意的地方:一利用两点式求出点与光源点连线的公式 x = ( y1*X-Y*x1 )/( y1 - Y ),二区间找点;

如果不清楚区间找点可以先做一下nyoj891

Lucky Light

Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 279    Accepted Submission(s): 78


Problem Description
We have a (point) light source at position (xL, yL) with yL > 0, and a finite series of line segments, all of finite non-zero length, given by the coordinates of their two endpoints. These endpoints are all different. The line segments are all situated above the x-axis (y > 0).

The segments cast their shadows onto the x-axis. We assume that the shadows of two segments either do not overlap at all, or have an overlap that has some non-zero width (they do not just touch). We also assume that for each segment its shadow is more than just one point, i.e., there is no segment that is directed toward the light source. The height of the light source (yL) is at least 1 unit larger than the y-coordinates of the endpoints of the line segments. This guarantees that indeed each line segment has a bounded shadow on the x-axis.

The collection of shadows divides the x-axis into dark and lighted areas (intervals). The problem is to determine the number of lighted areas — which is at least 2 (if there is at least one line segment, otherwise it is 1).

In the picture below the three line segments A, B and C cause three lighted areas, as indicated.


 



 


 

Input
The first line of the input file contains a single number: the number of test cases to follow. Each test case has the following format:

One line with one integer n with 0 ≤ n ≤ 100: the number of line segments.
One line with two integers xL and yL, the coordinates of the light source, separated by a single space. The coordinates satisfy -100 ≤ xL ≤ 100 and 1 ≤ yL ≤ 1,000.
n lines, each containing four integers xi, yi, ui and vi, separated by single spaces, that specify x- and y-coordinates of the two endpoints (xi, yi) and (ui, vi) of the ith line segment, where -100 ≤ xi, ui ≤ 100 and 0 < yi, vi < yL, for 1 ≤ i ≤ n.
 


 

Output
For every test case in the input file, the output should contain a single number, on a single line: the number of lighted areas.

 


 

Sample Input
  
  
2 3 50 60 55 45 30 35 64 39 92 18 20 30 40 16 2 -10 50 -10 1 10 11 -10 11 10 1
 


 

Sample Output
  
  
3 2
 

代码:

#include<stdio.h>
#include<algorithm>
using std::sort;
typedef struct{
	double st, en; //st是线段的端点与光源点投影到x轴上的较小的,en是较大的
}str;
str a[300];
int cmp( str a, str b )
{
	if( a.st - b.st < 0 ) return true;//按照从小到大对st排序
	return false; 
}
int main()
{
	int t, n, i;
	double X, Y, x1, x2, y1, y2;
	scanf( "%d", &t );
	while( t -- ){
		scanf( "%d", &n );
		scanf( "%lf%lf", &X, &Y );
		if( n == 0 ){
			printf( "1\n" );
			continue;
		}
		for( i = 0; i < n; i ++ ){
			scanf( "%lf%lf%lf%lf", &x1, &y1, &x2, &y2 );
			//printf( "%lf %lf %lf %lf\n", x1, y1, x2, y2 );
			a[i].st = ( y1*X-Y*x1 )/( y1 - Y );//求x的公式
            a[i].en = ( y2*X-Y*x2 )/( y2 - Y );
			if( a[i].st > a[i].en ){
				double temp = a[i].st;
				a[i].st = a[i].en;
				a[i].en = temp;
			}
		}
                     /*下面的是区间找点*/
		sort( a, a+n, cmp );
		double max = a[0].en;
		int ans = 0;
		for( i = 1; i < n; i ++ ){ 
			if( max < a[i].st ){
				++ans;
				max = a[i].en;
			}
			else if( max < a[i].en ){
				max = a[i].en;
			}
		}
		printf( "%d\n", ans+2 );
	//	for( i = 0; i < n; i ++ )
	//	printf( "%lf %lf\n", a[i].st, a[i].en );
	}
	return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值