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的更多相关文章

  1. Ural 1298 Knight 题解

    目录 Ural 1298 Knight 题解 题意 题解 程序 Ural 1298 Knight 题解 题意 给定一个\(n\times n(1\le n\le8)\)的国际象棋棋盘和一个骑士(基本上 ...

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

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

  3. 杭电ACM分类

    杭电ACM分类: 1001 整数求和 水题1002 C语言实验题——两个数比较 水题1003 1.2.3.4.5... 简单题1004 渊子赛马 排序+贪心的方法归并1005 Hero In Maze ...

  4. Ural 1197 - Lonesome Knight

    The statement of this problem is very simple: you are to determine how many squares of the chessboar ...

  5. Ural 2036. Intersect Until You're Sick of It 计算几何

    2036. Intersect Until You're Sick of It 题目连接: http://acm.timus.ru/problem.aspx?space=1&num=2036 ...

  6. URAL 1775 B - Space Bowling 计算几何

    B - Space BowlingTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/contest/ ...

  7. Ural 1046 Geometrical Dreams(解方程+计算几何)

    题目链接:http://acm.timus.ru/problem.aspx?space=1&num=1046 参考博客:http://hi.baidu.com/cloudygoose/item ...

  8. URAL 2099 Space Invader题解 (计算几何)

    啥也不说了,直接看图吧…… 代码如下: #include<stdio.h> #include<iostream> #include<math.h> using na ...

  9. URAL 1966 Cycling Roads 计算几何

    Cycling Roads 题目连接: http://acm.hust.edu.cn/vjudge/contest/123332#problem/F Description When Vova was ...

随机推荐

  1. 在JS中,一切东东其实都是对象

    对象是组成JavaScript的基本单元,在JS中,一切东东其实都是对象,而且功能非常强大,它不仅风格独特,功能也与众不同. 一.引用(reference) 引用的概念是JS的基础之一,它是指向对象实 ...

  2. GDB使用小记

    By francis_hao Nov 7,2016   记录GDB常用功能.   GDB可以让你查看一个程序在运行时其内部发生了什么,或者当一个程序崩溃时发生了什么(通过使用GDB查看core dum ...

  3. power designer 绘制E-R 图

    总体概括:本篇主要先介绍E-R图的一些基本概念,然后介绍怎么绘制E-R图,特别是用power designer 的反向工程怎么把表中对字段的注释也展示出来. 1.E-R图的基本概念: E-R图就是en ...

  4. python爬取七星彩的开奖历史记录

    1.因为人不可能一直无休止的学习,偶尔也想做点儿别的,昨天无聊就想写写Python,当然我承认我上班后基本都是在学工作方面的事情,在这个岗位我也呆了三年多了,还是那句话问我什么会不会我会给你说我啥都会 ...

  5. JavaScript获取HTML元素样式的方法(style、currentStyle、getComputedStyle)

    一.style.currentStyle.getComputedStyle的区别 style只能获取元素的内联样式,内部样式和外部样式使用style是获取不到的. currentStyle可以弥补st ...

  6. Asp.Net Core 基于QuartzNet任务管理系统(这是一篇用来水的随笔)

    之前一直想搞个后台任务管理系统,零零散散的搞到现在,也算完成了. 废话不多说,进入正题. github地址:https://github.com/YANGKANG01/QuartzNetJob 一.项 ...

  7. c# vs2008报表

    1. 做报表没做几次,第一次做的都忘记了,还好今天做一下就把报表弄成功了.报表中“参数字段”是可以变的,就是说需要自己赋值或者是要计算的.而在苏据库字段里面的是固定的值.不需要计算(注:有的字段查询出 ...

  8. 【LA3487】最小割-经典模型 两种方法

    题目链接 题意:A.B两个公司要买一些资源(他们自己买的资源不会重复),一个资源只能卖给一个公司.问最大收益. simple input 部分: 54 1 //买到1就给54元 15 2 33 3 2 ...

  9. angular2框架搭建,angular-cli使用,angular2学习

    angular红红火火很多年了,一眨眼ng4都出来了,我也只能叹息前端的日新月异,以及感叹自己永远追赶不上时代的步伐,但是没关系,一个优秀的前端不在于他懂的无数的框架,而在于遇到问题时候懂得如何学习, ...

  10. <script>中的async与defer属性

    1.script元素中的defer属性 1.1说明 使用该属性可以使脚本延迟到文档完全被解析和显示之后再按照原本的顺序执行,即告诉浏览器立即下载脚本,但延迟执行,该属性只对外部脚本有效 1.2使用方法 ...