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. 安卓tablayout控件的使用

    1.加载依赖 api "com.android.support:design:26.1.0" 2.布局 <android.support.design.widget.TabL ...

  2. bzoj 2756 [SCOI2012]奇怪的游戏 二分+网络流

    2756:[SCOI2012]奇怪的游戏 Time Limit: 40 Sec  Memory Limit: 128 MBSubmit: 4926  Solved: 1362[Submit][Stat ...

  3. css3 新旧伸缩盒的异同

    由于不需要理会IE浏览器,伸缩盒(flexible box)移动端开发中非常好用! 工作中使用APICLOUD开发手机App,老板要求兼容到安卓2.3(新版的需要安卓4.4以上),所以一直使用的是旧版 ...

  4. 创建Maven项目出现:An internal error occurred during: "Retrieving archetypes:". Java heap space 错误解决办法

    首先说明一下网上的方法: 在Eclipse中创建Maven的Web项目时出现错误:An internal error occurred during: "Retrieving archety ...

  5. session超时设置+超时页面跳转

    session超时设置,方法有三种: (1)在主页面或者公共页面中加入:session.setMaxInactiveInterval(600);参数600单位是秒,即在没有10分钟活动后,sessio ...

  6. 转: 构建基于Nginx的文件服务器思路与实现

    在Web项目中使用独立的服务器来保存文件和图片的好处很多,如:便于统一管理,分流web服务器的压力,可进行访问加速等.另外当web服务器需要做集群进行负载均衡时,图片和文件上传在各个服务器之间同步将是 ...

  7. C语言编译各过程

    1.预处理 此阶段主要完成#符号后面的各项内容到源文件的替换,往往一些莫名其妙的错误都是出现在头文件中的,要在工程中注意积累一些错误知识. (1).#ifdef等内容,完成条件编译内容的替换 (2). ...

  8. 51nodeE 斜率最大

    题目传送门 这道题只要证明最佳解一定在相邻两个点之间的好啦 这个自己证一证就okay啦 而且我发现n方的算法可以过耶... #include<cstdio> #include<cst ...

  9. unet中可视性检查的一些笔记

    最近在尝试用unet做一个局域网游戏,游戏的核心概念在于玩家之间的发现和隐蔽,有个类似于战争迷雾的机制. 实现该机制最关键的是实现可视性检查.首先是unet中默认的一个可视性检查,由组件Network ...

  10. python学习笔记 协程

    在学习异步IO模型前,先来了解协程 协程又叫做微线程,Coroutine 子程序或者成为函数,在所有语言中都是层级调用,比如a调用b,b调用c.c执行完毕返回,b执行完毕返回,最后a执行完毕返回 所以 ...