【计算几何】URAL - 2101 - Knight's Shield

Little Peter Ivanov likes to play knights. Or musketeers. Or samurai. It depends on his mood. For parents, it is still always looks like “he again found a stick and peels the trees.” They cannot understand that it is a sword. Or epee. Or katana.

Today Peter has found a shield. Actually, it is a board from the fence; fortunately, the nails from it have already been pulled. Peter knows that the family coat of arms should be depicted on the knight’s shield. The coat of arms of Ivanovs is a rectangle inscribed in a triangle (only grandfather supports Peter’s game, and he is, after all, a professor of mathematics). Peter has already drawn the triangle, and then noticed that there is a hole from a nail inside the triangle. It is not very good, so Peter wants to draw a rectangle in such a way that the hole will be on its border.

Because of the rectangle in Peter’s family symbolizes the authority and power then Peter wants to draw a rectangle of maximum area.

And due to the fact, that Peter is a grandson of grandfather-mathematician, he is also interested in purely theoretical question — how many different rectangles, satisfying the conditions, can be drawn in the triangle.

Help Peter to find the answers to these questions.

Input

The four lines contain the coordinates of four points that are the vertices of the triangle and the hole, respectively. All coordinates are integers and do not exceed 10 4 in absolute value. It is guaranteed that the hole is strictly inside the triangle. Also it is guaranteed that the triangle vertices do not lie on one line.

Output

In the first line output the maximum area of a rectangle, which Peter can draw. The answer will be considered correct if a relative or absolute error of maximum area does not exceed 10 ?6.

In the second line output the number of different rectangles that Peter can draw (these rectangles are not required to have the maximum area).

Example

input output
0 0
10 0
0 20
4 6
48.0000000000
4
-3 0
2 -1
5 7
0 1
9.0697674419
2

Notes

The rectangle is called inscribed in a triangle if all its vertices lie on the sides of the triangle.

把三角形按锐角、直角、钝角分类讨论,看点p是否在三条高上。锐角三角形的答案在3-6之间,直角在3-4之间,钝角在1-2之间。

需要求点在直线上的射影,然后再相似三角形啦,正切函数啥的啦搞一下面积就出来了。

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
#define EPS 0.00000001
struct Point
{
	double x,y;
	Point(const double &X,const double &Y)
	  {
	  	x=X;
	  	y=Y;
	  }
	Point(){}
	double Length()
	  {
	  	return sqrt(x*x+y*y);
	  }
}p,a[4];
typedef Point Vector;
double Dot(const Vector &a,const Vector &b)
{
	return a.x*b.x+a.y*b.y;
}
Vector operator - (const Vector &a,const Vector &b)
{
	return Vector(a.x-b.x,a.y-b.y);
}
Vector operator + (const Vector &a,const Vector &b)
{
	return Vector(a.x+b.x,a.y+b.y);
}
double Cross(const Vector &a,const Vector &b)
{
	return a.x*b.y-a.y*b.x;
}
double DisToLine(Point P,Point A,Point B)
{
	Vector v1=B-A,v2=P-A;
	return fabs(Cross(v1,v2))/v1.Length();
}
double tanget(Point a,Point b,Point c)//a是顶点
{
	double COS=Dot(b-a,c-a)/(b-a).Length()/(c-a).Length();
	double SIN=sqrt((1.0-COS*COS));
	return SIN/COS;
}
Vector operator * (const double &x,const Vector &v)
{
	return Vector(x*v.x,x*v.y);
}
Point GetLineProjection(Point P,Point A,Point B)
{
	Vector v=B-A;
	return A+(Dot(v,P-A)/Dot(v,v))*v;
}
double area;
int main()
{
	//freopen("b.in","r",stdin);
	for(int i=1;i<=3;++i)
	  scanf("%lf%lf",&a[i].x,&a[i].y);
	scanf("%lf%lf",&p.x,&p.y);
	int flag=0,ans=0;
	//钝角三角形
	if(Dot(a[2]-a[1],a[3]-a[1])<-EPS)
	  {
	  	double dis=DisToLine(p,a[2],a[3]);
	  	area=dis*((a[2]-a[3]).Length()-dis/tanget(a[2],a[1],a[3])-dis/tanget(a[3],a[1],a[2]));
	  	if(fabs(Dot(a[1]-p,a[2]-a[3]))<EPS)
	  	  ans=1;
	  	else
	  	  {
	  	  	ans=2;
	  	  	Point p1=GetLineProjection(a[1],a[2],a[3]);
	  	  	Point p2=GetLineProjection(p,a[2],a[3]);
	  	  	double h=(a[1]-p1).Length();
	  	  	double h1;
	  	  	if(Dot(p-p1,a[2]-p1)>EPS)
	  	  	  h1=(p2-a[2]).Length()/(p1-a[2]).Length()*h;
	  	  	else
	  	  	  h1=(p2-a[3]).Length()/(p1-a[3]).Length()*h;
	  	  	double l1=(h-h1)/h*(a[2]-a[3]).Length();
	  	  	area=max(area,h1*l1);
	  	  }
	  	printf("%.10lf\n%d\n",area,ans);
	  	return 0;
	  }
	else if(Dot(a[1]-a[2],a[3]-a[2])<-EPS)
	  {
	  	double dis=DisToLine(p,a[1],a[3]);
	  	area=dis*((a[1]-a[3]).Length()-dis/tanget(a[1],a[2],a[3])-dis/tanget(a[3],a[1],a[2]));
	  	if(fabs(Dot(a[2]-p,a[1]-a[3]))<EPS)
	  	  ans=1;
	  	else
	  	  {
	  	  	ans=2;
	  	  	Point p1=GetLineProjection(a[2],a[1],a[3]);
	  	  	Point p2=GetLineProjection(p,a[1],a[3]);
	  	  	double h=(a[2]-p1).Length();
	  	  	double h1;
	  	  	if(Dot(p-p1,a[1]-p1)>EPS)
	  	  	  h1=(p2-a[1]).Length()/(p1-a[1]).Length()*h;
	  	  	else
	  	  	  h1=(p2-a[3]).Length()/(p1-a[3]).Length()*h;
	  	  	double l1=(h-h1)/h*(a[1]-a[3]).Length();
	  	  	area=max(area,h1*l1);
	  	  }
	  	printf("%.10lf\n%d\n",area,ans);
	  	return 0;
	  }
	else if(Dot(a[1]-a[3],a[2]-a[3])<-EPS)
	  {
	  	double dis=DisToLine(p,a[1],a[2]);
	  	area=dis*((a[1]-a[2]).Length()-dis/tanget(a[1],a[2],a[3])-dis/tanget(a[2],a[1],a[3]));
	  	if(fabs(Dot(a[3]-p,a[1]-a[2]))<EPS)
	  	  ans=1;
	  	else
	  	  {
	  	  	ans=2;
	  	  	Point p1=GetLineProjection(a[3],a[1],a[2]);
	  	  	Point p2=GetLineProjection(p,a[1],a[2]);
	  	  	double h=(a[3]-p1).Length();
	  	  	double h1;
	  	  	if(Dot(p-p1,a[1]-p1)>EPS)
	  	  	  h1=(p2-a[1]).Length()/(p1-a[1]).Length()*h;
	  	  	else
	  	  	  h1=(p2-a[2]).Length()/(p1-a[2]).Length()*h;
	  	  	double l1=(h-h1)/h*(a[1]-a[2]).Length();
	  	  	area=max(area,h1*l1);
	  	  }
	  	printf("%.10lf\n%d\n",area,ans);
	  	return 0;
	  }
	//直角三角形
	if(fabs(Dot(a[2]-a[1],a[3]-a[1]))<EPS)
	  {
	  	double dis=DisToLine(p,a[2],a[3]);
	  	area=dis*((a[2]-a[3]).Length()-dis/tanget(a[2],a[1],a[3])-dis/tanget(a[3],a[1],a[2]));
	  	if(fabs(Dot(a[1]-p,a[2]-a[3]))<EPS)
	  	  ans=3;
	  	else
	  	  {
	  	  	ans=4;
	  	  	Point p1=GetLineProjection(a[1],a[2],a[3]);
	  	  	Point p2=GetLineProjection(p,a[2],a[3]);
	  	  	double h=(a[1]-p1).Length();
	  	  	double h1;
	  	  	if(Dot(p-p1,a[2]-p1)>EPS)
	  	  	  h1=(p2-a[2]).Length()/(p1-a[2]).Length()*h;
	  	  	else
	  	  	  h1=(p2-a[3]).Length()/(p1-a[3]).Length()*h;
	  	  	double l1=(h-h1)/h*(a[2]-a[3]).Length();
	  	  	area=max(area,h1*l1);

	  	  	Point p3=GetLineProjection(p,a[1],a[3]);
	  	  	double h2=(p3-a[3]).Length()/(a[1]-a[3]).Length()*(a[1]-a[2]).Length();
	  	  	Point p4=GetLineProjection(p,a[1],a[2]);
	  	  	double l2=(a[1]-a[3]).Length()-h2/tanget(a[3],a[1],a[2]);
	  	  	area=max(area,h2*l2);

	  	  	double h3=(p4-a[2]).Length()/(a[1]-a[2]).Length()*(a[1]-a[3]).Length();
	  	  	double l3=(a[1]-a[2]).Length()-h3/tanget(a[2],a[1],a[3]);
	  	  	area=max(area,h3*l3);
	  	  }
	  	printf("%.10lf\n%d\n",area,ans);
	  	return 0;
	  }
	else if(fabs(Dot(a[1]-a[2],a[3]-a[2]))<EPS)
	  {
	  	double dis=DisToLine(p,a[1],a[3]);
	  	area=dis*((a[1]-a[3]).Length()-dis/tanget(a[1],a[2],a[3])-dis/tanget(a[3],a[1],a[2]));
	  	if(fabs(Dot(a[2]-p,a[1]-a[3]))<EPS)
	  	  ans=3;
	  	else
	  	  {
	  	  	ans=4;
	  	  	Point p1=GetLineProjection(a[2],a[1],a[3]);
	  	  	Point p2=GetLineProjection(p,a[1],a[3]);
	  	  	double h=(a[2]-p1).Length();
	  	  	double h1;
	  	  	if(Dot(p-p1,a[1]-p1)>EPS)
	  	  	  h1=(p2-a[1]).Length()/(p1-a[1]).Length()*h;
	  	  	else
	  	  	  h1=(p2-a[3]).Length()/(p1-a[3]).Length()*h;
	  	  	double l1=(h-h1)/h*(a[1]-a[3]).Length();
	  	  	area=max(area,h1*l1);

	  	  	Point p3=GetLineProjection(p,a[2],a[3]);
	  	  	double h2=(p3-a[3]).Length()/(a[2]-a[3]).Length()*(a[1]-a[2]).Length();
	  	  	Point p4=GetLineProjection(p,a[1],a[2]);
	  	  	double l2=(a[2]-a[3]).Length()-h2/tanget(a[3],a[1],a[2]);
	  	  	area=max(area,h2*l2);

	  	  	double h3=(p4-a[1]).Length()/(a[1]-a[2]).Length()*(a[2]-a[3]).Length();
	  	  	double l3=(a[1]-a[2]).Length()-h3/tanget(a[1],a[2],a[3]);
	  	  	area=max(area,h3*l3);
	  	  }
	  	printf("%.10lf\n%d\n",area,ans);
	  	return 0;
	  }
	else if(fabs(Dot(a[1]-a[3],a[2]-a[3]))<EPS)
	  {
	  	double dis=DisToLine(p,a[1],a[2]);
	  	area=dis*((a[1]-a[2]).Length()-dis/tanget(a[1],a[2],a[3])-dis/tanget(a[2],a[1],a[3]));
	  	if(fabs(Dot(a[3]-p,a[1]-a[2]))<EPS)
	  	  ans=3;
	  	else
	  	  {
	  	  	ans=4;
	  	  	Point p1=GetLineProjection(a[3],a[1],a[2]);
	  	  	Point p2=GetLineProjection(p,a[1],a[2]);
	  	  	double h=(a[3]-p1).Length();
	  	  	double h1;
	  	  	if(Dot(p-p1,a[1]-p1)>EPS)
	  	  	  h1=(p2-a[1]).Length()/(p1-a[1]).Length()*h;
	  	  	else
	  	  	  h1=(p2-a[2]).Length()/(p1-a[2]).Length()*h;
	  	  	double l1=(h-h1)/h*(a[1]-a[2]).Length();
	  	  	area=max(area,h1*l1);

	  	  	Point p3=GetLineProjection(p,a[2],a[3]);
	  	  	double h2=(p3-a[2]).Length()/(a[2]-a[3]).Length()*(a[1]-a[3]).Length();
	  	  	Point p4=GetLineProjection(p,a[1],a[3]);
	  	  	double l2=(a[2]-a[3]).Length()-h2/tanget(a[2],a[1],a[3]);
	  	  	area=max(area,h2*l2);

	  	  	double h3=(p4-a[1]).Length()/(a[1]-a[3]).Length()*(a[2]-a[3]).Length();
	  	  	double l3=(a[1]-a[3]).Length()-h3/tanget(a[1],a[2],a[3]);
	  	  	area=max(area,h3*l3);
	  	  }
	  	printf("%.10lf\n%d\n",area,ans);
	  	return 0;
	  }
	//锐角三角形
	for(int i=1;i<=3;++i)//枚举上顶点
	  {
	  	int j,k;
	  	if(i==1) j=2,k=3;
	  	else if(i==2) j=3,k=1;
	  	else j=1,k=2;
	  	double dis=DisToLine(p,a[j],a[k]);
	  	area=max(area,dis*((a[j]-a[k]).Length()-dis/tanget(a[j],a[i],a[k])-dis/tanget(a[k],a[i],a[j])));
	  	if(fabs(Dot(a[i]-p,a[k]-a[j]))<EPS)
	  	  ++ans;
	  	else
	  	  {
	  	  	ans+=2;
	  		Point p1=GetLineProjection(a[i],a[j],a[k]);
	  	  	Point p2=GetLineProjection(p,a[j],a[k]);
	  	  	double h=(a[i]-p1).Length();
	  	  	double h1;
	  	  	if(Dot(p-p1,a[j]-p1)>EPS)
	  	  	  h1=(p2-a[j]).Length()/(p1-a[j]).Length()*h;
	  	  	else
	  	  	  h1=(p2-a[k]).Length()/(p1-a[k]).Length()*h;
	  	  	double l1=(h-h1)/h*(a[j]-a[k]).Length();
	  	  	area=max(area,h1*l1);
	  	  }
	  }
	printf("%.10lf\n%d\n",area,ans);
	return 0;
}

【计算几何】URAL - 2101 - Knight's Shield

时间: 2024-08-24 03:26:43

【计算几何】URAL - 2101 - Knight's Shield的相关文章

URAL 1298 knight dfs搜索

1298. Knight Time limit: 2.0 second Memory limit: 64 MB Even paratroopers have vacations. The flight to Sirius in the depths of "The Admiral Brisco" Leo Hao whiled away with chessboard. No, he did not like usual chess game, and in addition, he d

URAL 1298. Knight(DFS啊 )

题目链接:http://acm.timus.ru/problem.aspx?space=1&num=1298 1298. Knight Time limit: 2.0 second Memory limit: 64 MB Even paratroopers have vacations. The flight to Sirius in the depths of "The Admiral Brisco" Leo Hao whiled away with chessboard.

转载:hdu 题目分类 (侵删)

转载:from http://blog.csdn.net/qq_28236309/article/details/47818349 基础题:1000.1001.1004.1005.1008.1012.1013.1014.1017.1019.1021.1028.1029. 1032.1037.1040.1048.1056.1058.1061.1070.1076.1089.1090.1091.1092.1093. 1094.1095.1096.1097.1098.1106.1108.1157.116

杭电ACM分类

杭电ACM分类: 1001 整数求和 水题1002 C语言实验题——两个数比较 水题1003 1.2.3.4.5... 简单题1004 渊子赛马 排序+贪心的方法归并1005 Hero In Maze 广度搜索1006 Redraiment猜想 数论:容斥定理1007 童年生活二三事 递推题1008 University 简单hash1009 目标柏林 简单模拟题1010 Rails 模拟题(堆栈)1011 Box of Bricks 简单题1012 IMMEDIATE DECODABILITY

【转】对于杭电OJ题目的分类

[好像博客园不能直接转载,所以我复制过来了..] 1001 整数求和 水题1002 C语言实验题——两个数比较 水题1003 1.2.3.4.5... 简单题1004 渊子赛马 排序+贪心的方法归并1005 Hero In Maze 广度搜索1006 Redraiment猜想 数论:容斥定理1007 童年生活二三事 递推题1008 University 简单hash1009 目标柏林 简单模拟题1010 Rails 模拟题(堆栈)1011 Box of Bricks 简单题1012 IMMEDI

ural 1197. Lonesome Knight

每次knight都能在水平或竖直方向移动两格,然后到向左或右偏移一格: 直接枚举: 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 const int N=8; 6 const int M='h'-'a'+1; 7 8 int solve(int x,int y){ 9 int cnt=0; 10 11 if(x+2<=N){ 12 if

URAL 1750 Pakhom and the Gully 计算几何+floyd

题目链接:点击打开链接 gg.. . #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <iostream> #include <algorithm> #include <string.h> #include <vector> #include <queue> #include <math.h&

URAL 1203 Scientific Conference(贪心 || DP)

Scientific Conference 之前一直在刷计算几何,邀请赛连计算几何的毛都买见着,暑假这一段时间就做多校,补多校的题目,刷一下一直薄弱的DP.多校如果有计算几何一定要干掉-.- 题意:给你N个报告会的开始时间跟结束时间,问你做多可以听几场报告会.要求报告会之间至少间隔为1. 思路:其实是个活动安排问题,可以用贪心也可以用DP,贪心写起来会比较简单一些,因为练习DP,所以又用DP写了一遍. 贪心的话就是一个很简单的活动选择问题,从结束时间入手,找每次的最优选择. 1 struct n

【转】[专题学习][计算几何]

原文地址:http://www.cnblogs.com/ch3656468/archive/2011/03/02/1969303.html 基本的叉积.点积和凸包等东西就不多说什么了,网上一搜一大堆,切一些题目基本熟悉了就差不多了. 一些基本的题目可以自己搜索,比如这个blog:http://blog.sina.com.cn/s/blog_49c5866c0100f3om.html 接下来,研究了半平面交,思想方法看07年朱泽园的国家队论文,模板代码参考自我校大牛韬哥: http://www.o