2019ICPC南京——K

Triangle

题目链接
给定一个三角形,和三角形上一个点,求三角形上另一个点,两点将三角形分成面积均等的两份。
在这里插入图片描述
利用比值的思想,即可求解。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;

ll x1,x2,x3,y11,y2,y3,x,y;

bool check(ll x1,ll y11,ll x2,ll y2,ll x,ll y) {//判断给定点是不是在三角形的三条边上 
	if(x1==x2) {
		if(x==x1) {
			if(min(y11,y2)<=y&&y<=max(y11,y2))return true;
			else return false;
		} else {
			return false;
		}
	}
	if(y11==y2) {
		if(y==y11) {
			if(min(x1,x2)<=x&&x<=max(x1,x2))return true;
			else return false;
		} else {
			return false;
		}
	}
	ll cut = (y - y11) * (x2 - x1) - (x - x1) * (y2 - y11);
	if(cut==0) {
		if(min(x1,x2)<=x&&x<=max(x1,x2))return true;
		else return false;
	} else {
		return false;
	}
}

db len(ll x1,ll y11,ll x2,ll y2) {//两点的距离 
	return sqrt(1.0*(x1-x2)*(x1-x2)+1.0*(y11-y2)*(y11-y2));
}

db len2(ll x1,ll y11,ll x2,ll y2) {//两点的距离的平方 
	return 1.0*(x1-x2)*(x1-x2)+1.0*(y11-y2)*(y11-y2);
}

db S(ll x1,ll y11,ll x2,ll y2,ll x3,ll y3) {//给定三角形三个顶点求面积 
	db co=len2(x2,y2,x3,y3)+len2(x1,y11,x3,y3)-len2(x1,y11,x2,y2);
	co=co/(2.0*len(x2,y2,x3,y3)*len(x1,y11,x3,y3));//余弦公式:cosc=(a^2+b^2-c^2)/(2*a*b); 
	db si=sqrt(1.0-co*co);//sina^2+cosa^2==1;
	db ans=0.5*len(x2,y2,x3,y3)*len(x1,y11,x3,y3)*si;//三角形面积公式:S=a*b*sinc/2; 
	return ans;
}

db d(ll x1,ll y11,ll x2,ll y2,ll x,ll y) {//点到直线的距离 
	ll A=y11-y2;
	ll B=x2-x1;
	ll C=x1*(y2-y11)-y11*(x2-x1);
	double ans=fabs(1.0*A*x+1.0*B*y+1.0*C);
	ans=ans/sqrt(1.0*A*A+1.0*B*B);
	return ans;
}

int main() {
	int T;
	scanf("%d",&T);
	while(T--) {
		cin>>x1>>y11>>x2>>y2>>x3>>y3>>x>>y;
		int falg=0;
		if(!check(x1,y11,x2,y2,x,y))falg++;
		if(!check(x1,y11,x3,y3,x,y))falg++;
		if(!check(x2,y2,x3,y3,x,y))falg++;
		
		if(falg==3) {//给定点不在三条边上 
			printf("-1\n");
			continue;
		}
		
		if(falg==1) {//给定点在三角形定点上 
			db ansx=0,ansy=0;
			if(x==x1&&y==y11) {
				ansx=1.0*(x2+x3)/2;
				ansy=1.0*(y2+y3)/2;
			} else if(x==x2&&y==y2) {
				ansx=1.0*(x1+x3)/2;
				ansy=1.0*(y11+y3)/2;
			} else if(x==x3&&y==y3) {
				ansx=1.0*(x1+x2)/2;
				ansy=1.0*(y11+y2)/2;
			}
			printf("%.10lf %.10lf\n",ansx,ansy);
			continue;
		}
		//给定点在边上 
		db s=S(x1,y11,x2,y2,x3,y3);//三角形面积 
		if(check(x2,y2,x3,y3,x,y)) {//交换   保证给定点在1点和2点之间 
			swap(x1,x3),swap(y11,y3);
		}
		if(check(x1,y11,x3,y3,x,y)) {
			swap(x2,x3),swap(y2,y3);
		}

		db ansx,ansy;//保存答案 
		db hl=d(x1,y11,x3,y3,x,y);//右面的高 
		db hr=d(x2,y2,x3,y3,x,y);//左面的高 
		db dl=s/hl;//右面的底 
		db dr=s/hr;//左面的底 
		db kl=dl/len(x1,y11,x3,y3);//右面的底与右面的边的比值 
		db kr=dr/len(x2,y2,x3,y3);//左面的底与左面的边的比值 
		if(kl<=1.0) {
			ansx=1.0*x1+kl*(x3-x1);
			ansy=1.0*y11+kl*(y3-y11);
		} else {
			ansx=1.0*x2+kr*(x3-x2);
			ansy=1.0*y2+kr*(y3-y2);
		}
		printf("%.10lf %.10lf\n",ansx,ansy);
	}
	return 0;
}

计蒜客的编译器不让我定义y1,所以改成了y11,很别扭。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
UIUC ICPC Spring Coding Contest 2019是UIUC(伊利诺伊大学厄巴纳-香槟分校)举办的一个编程比赛。UIUC ICPC Spring Coding Contest 2019是ACM国际大学生程序设计竞赛(ACM International Collegiate Programming Contest)的一部分。ACM国际大学生程序设计竞赛是世界上最具影响力的大学生计算机竞赛之一,每吸引了来自全球各地的大学生参与。这个比赛旨在培养学生的算法和编程技能,提供一个展示和交流的平台。参赛者需要在规定时间内解决一系列编程问。 参加UIUC ICPC Spring Coding Contest 2019对于那些对算法和编程有兴趣的学生来说,是一个很好的学习和锻炼机会。比赛中的问通常涉及各种算法和数据结构,要求参赛者能够用编程语言实现有效和高效的解决方案。参赛者可以通过解决问来提高他们的算法和编程技能,并与其他参赛者交流和学习。 在准备UIUC ICPC Spring Coding Contest 2019之前,建议参赛者先掌握一些基本的编程知识和技能,如数据结构、算法、编程语言等。参赛者可以参考一些相关的教程和学习资料,如GeeksforGeeks和HackerEarth等网站提供的编程教程。此外,还可以参考一些竞赛经验分享的文章和博客,了解其他人是如何准备和参加编程比赛的。 总之,参加UIUC ICPC Spring Coding Contest 2019是一个很好的机会,可以提高算法和编程技能,与其他参赛者交流和学习。准备比赛前,建议参赛者掌握基本的编程知识和技能,并参考一些相关的教程和学习资料。祝你在比赛中取得好成绩!<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Awesome Competitive Programming Awesome](https://blog.csdn.net/qq_27009517/article/details/86593200)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值