基础
直线方程
知道两个点,\((x_1,y_1),(x_2,y_2)\),确定一条直线。\(Ax+By+C=0\)
\((y_1-y_2)\times x+(x_2-x_1)\times y+(x_1\times y_2-x_2\times y_1)=0\)
对角线数量
P2181 对角线 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
n个顶点的凸多边形,它的任何三条对角线都不会交于一点,(顶点不算交点).请求出图形中对角线交点的个数.
分析:一个交点确定两条对角线,确定四个点,则ans=C(4,n)
长方形最多的个数
N条水平线与M条竖直线构成的网格中,放K枚石子,每个石子都只能放在网格的交叉点上。最多可以找到多少四边平行于坐标轴的长方形且它的四个角上都恰好放着一枚石子。
结论:石子摆成接近矩形,只有一个缺口时最优。枚举矩形宽和长,取最大值。
P2180 摆石子 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
求三角形的面积
三个互不相同的点(x1,y1),(x2,y2),(x3,y3)
,求面积。
double a=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
double b=sqrt((x1-x3)*(x1-x3)+(y1-y3)*(y1-y3));
double c=sqrt((x2-x3)*(x2-x3)+(y2-y3)*(y2-y3));
double p=(a+b+c)/2;
double s=sqrt(p*(p-a)*(p-b)*(p-c))
求点和三角形的位置关系
1,若点在三角形内(不含边界)
2,若点在三角形外(不含边界)
3,若点在三角形边界上(不含顶点)
4,若点在三角形顶点上
判断内外时,点在里面时的面积=
三角形的面积;点在外面时,面积是四边形的面积
叉积
两个向量\(\vec{a},\vec{b}\)
模长:\(|\vec{a}\times \vec{b}|=|\vec{a}||\vec{b}|sin_\Theta\)
两条直线的交点
直线\(L_1=A_1x+B_1y+C_1=0,L_2=A_2x+B_2y+C_2=0\)
交点为\(x=(B_2C_1-B_1C_2)\div (A_2B_1-A_1B_2),y=(A_1C_2-A_2C_1)\div (A_2B_1-A_1B_2)\)
\(A_2B_1-A_1B_2=0\)时两直线平行
直线\(L_1=k_1x+b_1,L_2=k_2x+b_2\)
交点为\(x=(b_2-b_1)\div (k_1-k_2),y=(k_1b_2-k_2b_1)\div (k_1-k_2)\)
判断点在直线的哪边Q
直线上一点\(P(x_0,y_0)\)和方向向量\(\vec{v}=(a,b)\),判断点\(Q(x_1,y_1)\)在直线的哪边
计算\(|\vec{PQ}\times \vec{v}|\),结果<0,则点在直线上面;结果>0,点在直线下面;结果=0,在直线上
\(|\vec{PQ}\times \vec{v}|=(x_1-x_0)b-(y_1-y_0)a\)
凸包
凸多边形:所有内角大小都在[0,Π]
范围内的简单多边形。
凸包:在平面上能包含所有给定点的最小凸多边形。
USACO5.1]圈奶牛Fencing the Cows /【模板】二维凸包 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
Andrew算法
nlog(n)
int n;
struct node
{
double x, y;
};
node p[100005], s[100005];
double chaji(node x1, node x2, node y1, node y2)//检查叉积是否大于0,如果是a就逆时针转到b
{
return (x1.x - x2.x) * (y1.y - y2.y) - (x1.y - x2.y) * (y1.x - y2.x);
}
double dis(node x1, node x2)//两点间距离
{
return sqrt((x1.x - x2.x) * (x1.x - x2.x) + (x1.y - x2.y) * (x1.y - x2.y));
}
int cmp(node x1, node x2)//排序函数
{
double k = chaji(p[1], x1, p[1], x2);
if (k > 0)
return 1;
else if (k == 0 && dis(p[1], x1) < dis(p[1], x2))
return 1;
return 0;
}
int main()
{
scanf("%d", &n);
for (int i = 1; i <= n; i++)
{
scanf("%lf%lf", &p[i].x, &p[i].y);
if (i != 1 && p[i].y < p[1].y)
{
swap(p[i].y, p[1].y);
swap(p[i].x, p[1].x);
}
else if (i != 1 && p[i].y == p[1].y)
{
p[1].x = min(p[1].x, p[i].x);
}
}
//初始化,将最下面的那个点定为起始点(若有多个点选择最左边的),(这个点一定是凸包的顶点)
//将它交换到1号点
sort(p + 2, p + 1 + n, cmp);
int cnt = 1;
s[1] = p[1];
for (int i = 2; i <= n; i++)
{
while (cnt > 1 && chaji(s[cnt - 1], s[cnt], s[cnt], p[i]) <= 0)
cnt--;
cnt++;
s[cnt] = p[i];
}
//s[1~cnt]里面是凸包的顶点
return 0;
}