【计算几何】URAL - 2101 - Knight's Shield
Input
Output
Example
| input | output |
|---|---|
0 0 |
48.0000000000 |
-3 0 |
9.0697674419 |
Notes
把三角形按锐角、直角、钝角分类讨论,看点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的更多相关文章
- Ural 1298 Knight 题解
目录 Ural 1298 Knight 题解 题意 题解 程序 Ural 1298 Knight 题解 题意 给定一个\(n\times n(1\le n\le8)\)的国际象棋棋盘和一个骑士(基本上 ...
- 转载:hdu 题目分类 (侵删)
转载:from http://blog.csdn.net/qq_28236309/article/details/47818349 基础题:1000.1001.1004.1005.1008.1012. ...
- 杭电ACM分类
杭电ACM分类: 1001 整数求和 水题1002 C语言实验题——两个数比较 水题1003 1.2.3.4.5... 简单题1004 渊子赛马 排序+贪心的方法归并1005 Hero In Maze ...
- Ural 1197 - Lonesome Knight
The statement of this problem is very simple: you are to determine how many squares of the chessboar ...
- 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 ...
- URAL 1775 B - Space Bowling 计算几何
B - Space BowlingTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/contest/ ...
- Ural 1046 Geometrical Dreams(解方程+计算几何)
题目链接:http://acm.timus.ru/problem.aspx?space=1&num=1046 参考博客:http://hi.baidu.com/cloudygoose/item ...
- URAL 2099 Space Invader题解 (计算几何)
啥也不说了,直接看图吧…… 代码如下: #include<stdio.h> #include<iostream> #include<math.h> using na ...
- URAL 1966 Cycling Roads 计算几何
Cycling Roads 题目连接: http://acm.hust.edu.cn/vjudge/contest/123332#problem/F Description When Vova was ...
随机推荐
- spring aop与aspectj
AOP:面向切面编程 简介 AOP解决的问题:将核心业务代码与外围业务(日志记录.权限校验.异常处理.事务控制)代码分离出来,提高模块化,降低代码耦合度,使职责更单一. AOP应用场景: 日志记录.权 ...
- windows 系统下git 的使用
前言: 最新版本的git for windows也是有界面的,不再是以前的纯命令行操作,但是我习惯了乌龟,所以感觉还是直接用乌龟比较方便点~~ 前提,已安装以下: git for windows,未安 ...
- HDFS 的Trash回收站
1)在core-site.xml文件中添加这个配置 在每个节点(不仅仅是主节点)上添加配置 core-site.xml,增加如下内容 <property> <name>fs.t ...
- 使用FindBugs-IDEA插件找到代码中潜在的问题
另一篇使用文档,参照:https://www.cnblogs.com/huaxingtianxia/p/6703315.html 我们通常都会在APP上线之后,发现各种错误,尤其是空指针异常,这些错误 ...
- 【Foreign】染色 [LCT][线段树]
染色 Time Limit: 20 Sec Memory Limit: 256 MB Description Input Output Sample Input 13 0 1 0 2 1 11 1 ...
- 【BZOJ2049】【SDOI2008】洞穴勘测 [LCT]
洞穴勘测 Time Limit: 10 Sec Memory Limit: 259 MB[Submit][Status][Discuss] Description 辉辉热衷于洞穴勘测.某天,他按照地 ...
- linux下使用wget下载整个网站
linux下可以用wget下载整个网站,而且网站链接中包含utf-8编码的中文也能正确处理. 简要方法记录如下: wget --restrict-file-name=ascii -m -c -nv - ...
- Linux服务器中毒事件(libudev.so)
今天机房管理人员反馈公司的某台服务器在防火墙上的连接数超限,登陆服务器时发现非常卡顿,远程登录后查看,CPU持续100%,且有一长度为10的随机字符串进程,kill掉,会重新生成另外长度为10的字符串 ...
- 网络知识===cookie 、session、JSESSIONID的区别
cookie .session ? 让我们用几个例子来描述一下cookie和session机制之间的区别与联系.笔者曾经常去的一家咖啡店有喝5杯咖啡免费赠一杯咖啡的优惠,然而一次性消费5杯咖啡的机会微 ...
- 工作技能===开发不改bug?给你支个招
在测试过程中,不免会遇到开发人员因为一些原因不想修改个别bug的情况.那一般遇到这种问题时,我们该如何去推进开发修改bug呢? 我们先来分析下到底会有哪些原因会导致开发不修改bug 1. 开发与测试对 ...