白書幾何模板

2021-07-08 09:27:10 字數 2816 閱讀 8419

/*

白書幾何模板

*/const double eps = 1e-10;

struct point

};typedef point vector;//向量就是點的表示

vector operator + (vector a,vector b)

vector operator -(vector a,vector b)

vector operator *(vector a,double p)

vector operator /(vector a,double p)

//以上過載操作符

int dcmp(double x)

bool operator == (const point & a,const point & b)

double dot(vector a,vector b)

double length(vector a)

double angle(vector a,vector b)

double cross(vector a,vector b)

vector rotate(vector a,double rad)

vector normal(vector a)

point getlineintersection(point p,vector v,point q,vector w)

double distancetoline(point p,point a,point b)

point getllineprojection(point p,point a,point b)

bool segmentproperintersection(point a1,point a2,point b1,point b2)//如果c1,c2同時為0,則說明兩線段有部分重疊,如果不全為0,其中乙個為0,則說明乙個線段的端點在另乙個線段上

bool onsegment(point p,point a1,point a2)

/*以下為和圓有關的函式

*/struct circle

circle(){}

point point(double a)

};//求圓和直線的交點,假設直線為ab,圓為c,得到修改的t1,t2,若存在的話,則交點p是a + ti * (b - a)

int getlinecircleintersection(point a,point b,circle c,double &t1,double &t2)

//接下來是相交

t1 = (-f - sqrt(delta)) / (2 * e);

t2 = (-f + sqrt(delta)) / (2 * e);

}//以下為求兩圓的交點

double angle(vector v)//其中atan2(y,x)表示出發點是原點,目標點是(x,y)的射線與x正半軸的夾角的角度

//如果有交點,設交點為p1,p2

int getcirclecircleintersection(circle c1,circle c2,vector& sol)

} if(dcmp(c1.r + c2.r - d) < 0)return 0;//兩圓半徑相加小於距離,外離

if(dcmp(fabs(c1.r - c2.r) - d) > 0)return 0;//大圓包含小圓

double a = angle(c2.c - c1.c);//向量c1c2的極角

double da = acos((c1.r * c1.r + d * d - c2.r * c2.r) / (2 * c1.r * d));//c1c2到c1p1的角

point p1 = c1.point(a - da),p2 = c1.point(a + da);

sol.push_back(p1);

if(p1 == p2)return 1;//相切

sol.push_back(p2);

return 2;

}//以下為從乙個點出發,求已知圓的切線

//過點p到圓c的切線,v[i]是第i條切線,返回切線數

int gettangents(point p,circle c,vector&v)else

}//以下為知道兩個圓,求兩個圓的公切線

int gettangents(circle a,circle b,vector&a,vector&b)

int d2 = (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);

int rdiff = a.r - b.r;

int rsum = a.r + b.r;

if(d2 < rdiff * rdiff)return 0;//內含無切線

double base = atan2(b.y - a.y,b.x - a.x);

if(d2 == 0 && a.r == b.r)return -1;//兩圓重合,無限多條切線

if(d2 == rdiff * rdiff)

//以上為乙個圓在另乙個園內,以下為有外公切線

double ang = acos((a.r - b.r) / sqrt(d2));

a.push_back(a.getpoint(base + ang));b.push_back(b.getpoint(base + ang));

a.push_back(a.getpoint(base - ang));b.push_back(b.getpoint(base - ang));

if(d2 == rsum * rsum)else if(d2 > rsum * rsum)

return cnt;//返回切線條數

}

白書若干題

1.p32 排列 用1 2 3 9組成3個三位數abc,def和ghi,每個數字恰好使用一次,要求abc def ghi 1 2 3。輸出所有解。int i,j,k for i 123 i 987 3 i next permutation等全部重拍,然後判斷是否滿足比例關係。2.p50 乘積的末三位...

劃分數 白書

1 include 2 include 3 4using namespace std 5 有關計數問題的dp6 有n個無區別的物品,劃分成不超過m組,求方法數取模m的餘數78 const int max n 1000 2 9 const int max m 1000 2 10 const int m...

白書16 12凸包

安德魯演算法 安德魯演算法判斷凸包需要用到叉積 關於叉積 首先在二維座標下介紹一些定義 點 a x1,y1 b x2,y2 向量 向量ab x2 x1 y2 y1 x y 向量的模 ab sqrt x x y y 向量的點積 結果為 x1 x2 y1 y2。點積的結果是乙個數值。點積的集合意義 我們...