因为这篇文章写得时候我特别菜,还不会 LaTeX \LaTeX LATEX,而且表述中又不少不是很明确的地方,大家可以看余弦定理的证明及其应用 改进版以追求更好的阅读体验qwq
余弦定理
余弦定理,顾名思义,与余弦函数cos有关,具体的是这样的

对于任意一个三角形ABC,有如下结论
a2=b2+c2-2bc·cosA
b2=a2+c2-2ac·cosB
c2=a2+b2-2ab·cosC
为什么呢?
余弦定理的证明
在上面那张图中其实大家就能看到证明方法
向量:有向的线段,向量AC打印体记做AC 具体的大家可以参阅百度百科

首先,我们根据向量的加法,得到等式
a+b=c
a=c–b
a2=(c–b)2
a2=b2+c2-2·b·c
a2=b2+c2-2|b|·|c|·cosA (向量的数量积)
a2=b2+c2-2bc·cosA
得证
余弦定理的应用
讲完了证明,我们来看看余弦定理的应用
洛谷p2625 豪华游轮
题目描述(这里不是向量…)
有一条豪华游轮(其实就是条小木船),这种船可以执行4种指令:
right X : 其中X是一个1到719的整数,这个命令使得船顺时针转动X度。
left X : 其中X是一个1到719的整数,这个命令使得船逆时针转动X度。 forward X : 其中X是一个整数(1到1000),使得船向正前方前进X的距离。
backward X : 其中X是一个整数(1到1000),使得船向正后方前进X的距离。
随意的写出了n个命令,找出一个种排列命令的方法,使得船最终到达的位置距离起点尽可能的远。
输入输出格式
输入格式:
第一行一个整数n(1 <= n <= 50),表示给出的命令数。
接下来n行,每行表示一个命令。
这道题我们看到之后很快就能够反映出来,这个地方需要做一个贪心
因为多次拐弯肯定比一次的要近,所以我们让forward走完,然后尽量转180度,然后把backward走完,这时候起点和终点之间的距离就是要算的答案了
for(int i=1,i<=anglecnt;i++) for(int j=0;j<=360;j++){
if(f[i-1][j]){
f[i][j]=true; f[i][(j+angle[i]+360)%360]=true; } }
那好了,我们现在知道了旋转角度,知道了两边的边长,那么我们就可以使用余弦定理了啊
printf("%.6lf\n",sqrt(a*a+b*b-2*a*b*cos(degree*pi/180)));
这里运用的是弧度制,如果不理解的话可以上网去搜一搜
全代码大概是这样的
# include
# include
# include
# include
# include
# define Rep(i,a,b) for(int i=a;i<=b;i++) # define _Rep(i,a,b) for(int i=a;i>=b;i--) using namespace std; const int N=55; const double pi=3.979; int n,go,back,angle[N],a,b,degree=INT_MAX; bool f[N][1005]; char s[N]; int main() {
scanf("%d",&n); Rep(i,1,n){
int x; scanf("%s%d",s,&x); if(s[0]=='f') a+=x; if(s[0]=='b') b+=-x; if(s[0]=='l') angle[++angle[0]]=x; if(s[0]=='r') angle[++angle[0]]=-x; } f[0][0]=true; Rep(i,1,angle[0]) Rep(j,0,360){
if(f[i-1][j]){
f[i][j]=true; f[i][(j+angle[i]+360)%360]=true; } } Rep(i,0,360) if(f[angle[0]][i]) degree=min(degree,abs(180-i)); printf("%.6lf\n",sqrt(a*a+b*b-2*a*b*cos(degree*pi/180))); return 0; }
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/228380.html原文链接:https://javaforall.net
