向量
-
既有大小,又有方向的量,如速度
-
表示方法:字母上加箭头 a → \overrightarrow{a} a
-
向量的大小:表示为 ∣ a → ∣ |\overrightarrow{ \ a \ }| ∣ a ∣或 ∣ A B → ∣ |\overrightarrow{ \ AB \ }| ∣ AB ∣
-
在平面直角坐标系中,将向量 a → \overrightarrow{a} a平移,使起点与原点重合,终点位于点 ( x , y ) (x,y) (x,y),则实数对 ( x , y ) (x,y) (x,y)为向量 a → \overrightarrow{ \ a \ } a 的坐标,记为 a → = ( x , y ) \overrightarrow{ \ a \ }=(x,y) a =(x,y)
-
加法: A → + B → = ( x 1 + x 2 , y 1 + y 2 ) \overrightarrow{ \ A \ }+\overrightarrow{ \ B \ }=(x_1+x_2,y_1+y_2) A + B =(x1+x2,y1+y2)
-
减法: A → − B → = ( x 1 − x 2 , y 1 − y 2 ) \overrightarrow{ \ A \ }-\overrightarrow{ \ B \ }=(x_1-x_2,y_1-y_2) A − B =(x1−x2,y1−y2)
-
向量加减法满足交换律和结合律
-
若 A ( x 1 , y 1 ) , B ( x 2 , y 2 ) A(x_1,y_1),B(x_2,y_2) A(x1,y1),B(x2,y2),则 A B → = B − A \overrightarrow{AB}=B-A AB=B−A
点积
- 点积就是 a ⋅ b = x 1 x 2 + y 1 y 2 a⋅b=x_1x_2+y_1y_2 a⋅b=x1x2+y1y2
- 几何意义:两个向量的夹角
- 点积的性质:
- a ⋅ b = 0 a⋅b=0 a⋅b=0,则 a ⊥ b a\bot b a⊥b
- a ⋅ b < 0 a⋅b<0 a⋅b<0,则夹角 > 9 0 ∘ >90^\circ >90∘
- a ⋅ b > 0 a⋅b>0 a⋅b>0,则夹角 < 9 0 ∘ <90^\circ <90∘
叉积
- 叉积就是 a × b = x 1 y 2 − x 2 y 1 a\times b=x_1y_2-x_2y_1 a×b=x1y2−x2y1
- 几何意义:两个向量起点共点时,形成的四边形的面积
- 叉积的性质:
- a × b = 0 a\times b=0 a×b=0, a a a和 b b b平行
- a × b > 0 a\times b>0 a×b>0, a a a在 b b b顺时针方向
- a × b < 0 a\times b<0 a×b<0, a a a在 b b b逆时针方向
凸包
平面凸包指能覆盖平面上 n n n个点的最小的凸四边形,我们可以使用Graham扫描法来求点和周长。
Graham扫描法的步骤如下:
- 找到最左下的点作为原点
- 将其他点与原点连一条线段,计算出线段与水平线的夹角,按夹角从小到大排序。若夹角相同,优先选择距离原点近的点。
- 维护一个栈,将前两个点放进栈中,遍历3~n。设栈顶前一个点为 A 1 A_1 A1,栈顶的点为 A 2 A_2 A2,枚举到的点为 A 3 A_3 A3
- 如果 A 1 A 3 A_1A_3 A1A3在 A 1 A 2 A_1A_2 A1A2顺时针方向,则 A 2 A_2 A2在凹陷处,应该删除,栈顶元素出栈,继续比较
- 如果 A 1 A 3 A_1A_3 A1A3在 A 1 A 2 A_1A_2 A1A2顺时针方向,则将 A 3 A_3 A3压入栈中
- 遍历完后,栈中的点就是凸包上的点,周长为 ∣ s 1 s t o p → ∣ + ∑ i = 1 t o p ∣ s i s i + 1 → ∣ |\overrightarrow{s_1s_{top}}|+\sum\limits_{i=1}^{top}|\overrightarrow{s_is_{i+1}}| ∣s1stop∣+i=1∑top∣sisi+1∣
例题
P2742 [USACO5.1]Fencing the Cows
code
#include<bits/stdc++.h>
using namespace std;
int n,bz=1,tp,h[100005];
double ans=0;
struct node{
double x,y;
}w[100005];
bool pt(node v1,node v2,node v3){
if((v2.x-v1.x)*(v3.y-v1.y)-(v2.y-v1.y)*(v3.x-v1.x)<=0) return 1;
return 0;
}
double dis(node ax,node bx){
return sqrt((ax.x-bx.x)*(ax.x-bx.x)+(ax.y-bx.y)*(ax.y-bx.y));
}
bool cmp(node ax,node bx){
double v1=atan2(ax.y-w[1].y,ax.x-w[1].x),v2=atan2(bx.y-w[1].y,bx.x-w[1].x);
if(v1==v2) return dis(w[1],ax)<dis(w[1],bx);
return v1<v2;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%lf%lf",&w[i].x,&w[i].y);
if(w[bz].y>w[i].y||w[bz].y==w[i].y&&w[bz].x>w[i].x) bz=i;
}
swap(w[1],w[bz]);
sort(w+2,w+n+1,cmp);
h[++tp]=1;h[++tp]=2;
for(int i=3;i<=n;i++){
if(w[i].x==w[i-1].x&&w[i].y==w[i-1].y) continue;
while(tp>=2&&pt(w[h[tp-1]],w[h[tp]],w[i])) --tp;
h[++tp]=i;
}
h[tp+1]=h[1];
for(int i=1;i<=tp;i++){
ans+=dis(w[h[i]],w[h[i+1]]);
}
printf("%.2f",ans);
return 0;
}