JZOJ 3736.数学题【数学】

本文探讨了一种解决向量问题的算法,通过调整向量间的夹角来找到最短距离,涉及向量模长、夹角计算及向量调整等核心步骤,适用于初等数学和计算机图形学领域的向量运算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


题目:

传送门


题意:

直接看题目吧,已经很简略了


分析:

我们先证明当夹角大于 60 60 60度时,答案就是两个向量中模长较小的那一个
在这里插入图片描述
解释一下之所以上面所证明的是夹角大于 60 60 60度的,是因为只有当夹角在这种情况下 2 c o s   α 2cos\ \alpha 2cos α才小于 1 1 1,所以可以省略
但是肯定存在一开始夹角不足 60 60 60度的情况,所以我们再来证明如何将夹角放大
在这里插入图片描述


代码:

#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<cmath>
#define LZX Mu
#define LL long long 
using namespace std;
inline LL read() {
    LL d=0,f=1;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
    while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();}
    return d*f;
}
LL x1,x2,Y1,Y2;
LL cross() {return x1*Y2-x2*Y1;}
LL dot() {return x1*x2+Y1*Y2;}
double dis(LL x,LL y) {return sqrt(x*x+y*y);}
double getcross() {return (double)dot()/dis(x1,Y1)/dis(x2,Y2);}
int main()
{
//	freopen("math.in","r",stdin);
//	freopen("math.out","w",stdout);
	while(scanf("%lld%lld%lld%lld",&x1,&Y1,&x2,&Y2)!=EOF)
	{
		if(!cross()) {printf("0\n");continue;} 
		while(1)
		{
			if(dis(x1,Y1)>dis(x2,Y2)) {swap(x1,x2);swap(Y1,Y2);}
			double a=getcross();
			if(a<0) {x1=-x1;Y1=-Y1;continue;}
			if(a<0.5) break;
			LL k=dis(x2,Y2)*a/dis(x1,Y1)+0.5;
			x2-=k*x1;Y2-=k*Y1;
		}
		printf("%lld\n",min(x1*x1+Y1*Y1,x2*x2+Y2*Y2));
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值