nyoj 142, poj 1039 ,hdu 1454 管道問題

http://acm.nyist.net/JudgeOnline/problem.php?pid=142php

 

第一道解析幾何問題,比較糾結,主要是幾個解析幾何的基本操做,包括求兩線段的叉積,判斷左右方向,判斷是否相交, 計算交點等等,主要的思路就是窮舉全部的折點的組合,取任意兩個折點組成一條線,看看能不能跟全部的管道的上下折點構成的線段相交,若是全部都相交則說明光線能經過,不然求出全部光線中照的最遠的那個(窮舉的過程當中設置一個記錄變量) 這裏就須要計算兩個線段的交點(若是不能穿過管道,就要計算管道壁和光線的交點)。 .net

#include<stdio.h>
#include<math.h>
struct point
{
	double x, y;
};
double det(double x1, double y1, double x2, double y2) //計算叉積
{
	return x1 * y2 - x2 * y1;
}
double cross(point a, point b, point p)  //判斷左右方向
{
	return det(b.x - a.x, b.y - a.y, p.x - a.x, p.y - a.y);
}
double check(point a1, point a2, point b1, point b2) //判斷是否相交
{
	return cross(a1, a2, b1) * cross(a1, a2, b2);
}
double getarea(point a, point b, point c)
{
	double ab = sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
	double ac = sqrt((a.x - c.x) * (a.x - c.x) + (a.y - c.y) * (a.y - c.y));
	double bc = sqrt((c.x - b.x) * (c.x - b.x) + (c.y - b.y) * (c.y - b.y));
	double q = (ab + ac + bc) / 2;
	return sqrt(q * (q - ab) * (q - ac) * (q - bc));
}
double calculate(point a1, point a2, point b1, point b2)//計算x座標值
{
	double s1 = getarea(a1, a2, b1);
	double s2 = getarea(a1, a2, b2);
	return (s1 * b2.x + s2 * b1.x) / (s1 + s2);
}
int main()
{
	int n;
	while(scanf("%d", &n), n != 0)
	{
		int i;
		point pip[25][2];
		for(i = 0; i < n; i++)
		{
			scanf("%lf %lf", &pip[i][0].x, &pip[i][0].y);
			pip[i][1].x = pip[i][0].x;
			pip[i][1].y = pip[i][0].y - 1;
		}
		int j;
		double max_x = -0x7fffffff;
		bool flag = false;
		point a, b;
		for(i = 0; i < n && flag == false; i++)
		{
			int index1, index2;
			int temp = 0;
			for(temp = 0; temp < 2; temp ++)
			{
				a = pip[i][temp];
				for(index1 = i + 1 ; index1 < n && flag == false; index1 ++)
				{
					for(index2 = 0; index2 < 2 && flag == false; index2 ++)
					{	
						b = pip[index1][index2];
						if( check(a, b, pip[0][0], pip[0][1]) - 0 < 1e-6 )
						{
							for(j = 1; j < n; j++)
							{
								if( check(a, b, pip[j][0], pip[j][1]) - 0 > 1e-6)
								{
									double x;
									if(cross(a, b, pip[j][0]) > 0)
										x = calculate(a, b, pip[j - 1][1], pip[j][1]);
									else
										x = calculate(a, b, pip[j - 1][0], pip[j][0]);
									if(x > max_x)
										max_x = x;
									break;
								}
							}
							if(j == n)
								flag = true;
						}
					}
				}
			}
		}
		if(flag == true)
			printf("Through all the pipe.\n");
		else
			printf("%.2lf\n", max_x);
	}
	return 0;
}
相關文章
相關標籤/搜索