你最愿意做的哪件事,才是你的天赋所在

0%

基础计算机和-基础部分

两直线交点

首先我们知道两点能够确定一条直线,能够得到直线的方程

假设现在有两条直线

联立两个方程就可以得到一个简答的答案

实际上就是联立了方程组

利用线性代数的解法转换为行列式就是

解出的i,j,k对应x,y,d;

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include<bits/stdc++.h>
using namespace std;
#define ll long long
struct Point{
double x,y;
};
struct line
{
double a,b,c;
};
line getline(Point p1,Point p2)
{
return line{1/(p2.x-p1.x),-1/(p2.y-p1.y),(p1.y/(p2.y-p1.y)-p1.x/(p2.x-p1.x))};//取得方程
}
Point solve(line l1,line l2)
{
double D = l1.a*l2.b-l2.a*l1.b;
if(D==0)return Point{1e18,1e18};//平行或者重合
return Point{l1.b*l2.c-l2.b*l1.c/D,l2.a*l1.c-l1.a*l2.c/D};//返回点的坐标
}
int main()
{
solve(l1,l2);
}

求任意多边形的面积

叉乘

假设向量$\vec{a}=(x_1,y_1),\vec{b}=(x_2,y_2)$
那么向量的叉乘定义为

结果也就是两个向量构成三角形面积的两倍,使用这个方法开求多边形的面积
,假设多边形的点为$p_1,p_2\cdots,p_n;v_i为辅助点O与p_i的向量$。

圆与直线的关系

直线与圆的交点

相离,相交,相切,可以通过圆心与直线的距离和半径的大小比较来判断

圆与圆的交点

通过圆心得距离与两个圆得半径和来判断圆与圆之间的关系,有外离,内含,相交,相切

外离

当$r1+r2<d$时,两个圆无交点,为外离

内含

当$r1>d||r2>d$时为内含

相切

当$r1+r2==d$时,为相切,相切的情况下,就可以转化为直线与圆的关系求出切点。

相交

当$r1+r2<d$时,相交,相交求交点的做法联立两个方程带入即可

极角排序

叉积排序,atan2排序与象限排序
叉积排序速度慢,精度高,但是可能会炸范围,atan2精度低,单是速度块。

叉积排序

选定基准点$O(x,y)$

1
2
3
4
5
6
7
8
double Cross(Point p1,Cross p2)//叉积
{
return p1.x*p2.y-p2.x-p1.y;
}
bool cmp(Point p1,Point p2){
if(Cross(p1,p2)==0)return p1.x<p2.x;若极角相同返回x小的
reutrn Cross(p1,p2)>0;
}

atan2排序

1
2
3
4
5
6
atan2(double y,double x);//返回(x,y)与(0,0)与x正轴之间的夹角弧度
bool com(Point p1,Point p2)
{
if(atan2(p1.y,p1.x)-atan2(p2.y,p2.x)!=0)return atan2(p1.y,p1.x)<atan2(p2.y,p2.x);
else return p1.x<p2.x;
}

象限排序

1
2
3
4
5
6
7
8
9
10
11
12

int Quadrant(Point A){//返回所在象限
if(A.x>0&&A.y>=0)return 1;
if(A.x<=0&&A.y>0)return 2;
if(A.x<0&&A.y<=0)return 3;
if(A.x>=0&&A.y<0)return 4;
}
bool cmp2(Point A,Point B){//以原点为极点,先按照象限排序
if(Quadrant(A)==Quadrant(B))
return cmp1(A,B);//象限相同时,按照极角排序
else return Quadrant(A)<Quadrant(B);
}

例题

Poj1696

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include<stdio.h>
#include<math.h>
#include<algorithm>
using namespace std;
#define ll long long
const int N = 1e5+10;
#define eps
struct Point{
double x,y;
int id;
}Pole,p[N];
struct Vector{
double x,y;
};
int syn(double x)
{
if(fabs(x)<1e-8)return 0;
else if(x>0)return 1;
return -1;
}
double Cross(Vector a,Vector b){return a.x*b.y-a.y*b.x;}
Vector operator - (Point a,Point b){return {a.x-b.x,a.y-b.y};}
bool cmp(Point a,Point b)
{
if(syn(Cross(a-Pole,b-Pole))==0)return a.x<b.x;
return Cross(a-Pole,b-Pole)>0;
}
int n;
void solve()
{
scanf("%d",&n);
int index = 1;
for(int i=1;i<=n;i++)
{
scanf("%d%lf%lf",&p[i].id,&p[i].x,&p[i].y);
if(i!=1&&p[index].y>p[i].y)index=i;
else if(i!=1&&p[index].y==p[i].y&&p[i].x<p[index].x)index=i;
}
swap(p[1],p[index]);
Pole = p[1];
for(int i=2;i<=n;i++)
{
sort(p+i,p+1+n,cmp);
Pole=p[i];
}
printf("%d",n);
for(int i=1;i<=n;i++)
{
printf(" %d",p[i].id);
}
printf("\n");
}
int main()
{
int t;
scanf("%d",&t);
while(t--)solve();
}
-------------你最愿意做的哪件事才是你的天赋所在-------------