1035 - Tree-Lined Streets

The city council of Greenville recently voted to improve the appearance of inner city streets. To provide more greenery in the scenery, the city council has decided to plant trees along all major streets and avenues. To get an idea of how expensive this urban improvement project will be, the city council wants to determine how many trees will be planted. The planting of trees is limited in two ways:

  • Along a street, trees have to be planted at least 50 meters apart. This is to provide adequate grow ing space, and to keep the cost of the project within reasonable limits.
  • Due to safety concerns, no tree should be planted closer than 25 meters along a street to the nearest int ersection. This is to ensure that traffic participants can easily see each other approaching an intersection. Traffic safety should not be compromised by reducing visibility.

All streets considered in this project are straight . They have no turns or bends.

The city council needs to know the maximum number of trees that can be planted under these two restrictions.

Input 

The input consists of descriptions of several street maps. The first line of each description contains an integer  n  (   1$ \le$n$ \le$100 ), which is the number of streets in the map. Each of the following  n  lines describes a street as a line segment in the Cartesian plane. An input line describing a street contains four integers x1 y1 x2 , and  y2 . This means that this street goes from point  (x1y1)  to point  (x2y2) . The coordinates x1 y1 x2 , and  y2  are given in meters, (   0$ \le$x1, y1, x2, y2$ \le$100000 ). Every street has a positive length. Each end point lies on exactly one street.

For each street, the distances between neighboring intersections and/or the end points of the street are not exact multiples of 25 meters. More precisely, the difference of such a distance to the nearest multiple of 25 meters will be at least 0.001 meters. At each intersection, exactly two streets meet.

Input for the last street map description is followed by a line consisting of the number 0.

Output 

For each street map described in the input, first print its number in the sequence. Then print the maximum number of trees that can be planted under the restrictions specified above. Follow the format in the sample output given below.

Sample Input 

3
0 40 200 40
40 0 40 200
0 200 200 0
4
0 30 230 30
0 200 230 200
30 0 30 230
200 0 200 230
3
0 1 121 1
0 0 121 4
0 4 121 0
0

Sample Output 

Map 1
Trees = 13
Map 2
Trees = 20
Map 3
Trees = 7



#include<stdio.h>
#include<math.h>
#include<algorithm>
using namespace std;
struct line
{
	int x1,y1,x2,y2;
};
int cases,n,ans,s,i,j,k;
line a[110];
double b[200];
double len;

bool init()
{
	int i;
	scanf("%d",&n);
	if(n==0)
		return false;
	for(i=1;i<=n;i++)
		scanf("%d %d %d %d",&a[i].x1,&a[i].y1,&a[i].x2,&a[i].y2);
	return true;
}

double dis(double x,double y)
{
	return sqrt(x*x+y*y);
}

bool check(int x1,int y1,int x2,int y2,int x3,int y3)
{
	long long t1,t2;
	t1=(long long)x1*(long long)y2-(long long)x2*(long long)y1;
	t2=(long long)x1*(long long)y3-(long long)x3*(long long)y1;
	return ((t1>=0&&t2<=0)||(t1<=0&&t2>=0));
}

void cross(line A,line B)
{
	double A1,B1,C1,A2,B2,C2,x,y;
	A1=A.y2-A.y1;B1=A.x1-A.x2;C1=-(A.x1*A1 + A.y1*B1);
	A2=B.y2-B.y1;B2=B.x1-B.x2;C2=-(B.x1*A2 + B.y1*B2);
	x=-(C1*B2-C2*B1)/(A1*B2-A2*B1);
	y=-(A1*C2-A2*C1)/(A1*B2-A2*B1);
	b[s]=dis(x-a[i].x1,y-a[i].y1);
}

int main()
{
	cases=0;
	while(init())
	{
		ans=0;
		for(i=1;i<=n;i++)
		{
			s=2;
			b[1]=-25;
			b[2]=dis(a[i].x2-a[i].x1,a[i].y2-a[i].y1)+25;
			for(j=1;j<=n;j++)
				if(i!=j)
				if(check(a[i].x2-a[i].x1,a[i].y2-a[i].y1, a[j].x1-a[i].x1,a[j].y1-a[i].y1, a[j].x2-a[i].x1,a[j].y2-a[i].y1))
				if(check(a[j].x2-a[j].x1,a[j].y2-a[j].y1, a[i].x1-a[j].x1,a[i].y1-a[j].y1, a[i].x2-a[j].x1,a[i].y2-a[j].y1))
				{
					s++;cross(a[i],a[j]);
				}
				sort(b+1,b+s+1);
				for(j=1;j<s;j++)
				{
					len=b[j+1]-b[j];
					k=(int)(len/50);
					while(len-k*50>1e-6) k++;
					while(len-k*50<1e-6) k--;
					ans+=k;
				}
		}
		printf("Map %d\nTrees = %d\n",++cases,ans);
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值