浙江大学 acm程序设计竞赛 培训 线段树共66页文档

合集下载

浙江大学 acm程序设计竞赛 培训 线段树共68页文档

浙江大学 acm程序设计竞赛 培训 线段树共68页文档
浙江大学 acm程序设计竞赛 培训 线段 树
61、辍学如磨刀之石,不见其损,日 有所亏 。 62、奇文共欣赞,疑义相与析。
63、暧暧远人村,依依墟里烟,狗吠 深巷中 ,鸡鸣 桑树颠 。 64、一生复能几,倏如流电惊。 65、少无适俗韵,性本爱丘山。
61、奢侈是舒适的,否则就不是奢侈 。——CocoCha nel 62、少而好学,如日出之阳;壮而好学 ,如日 中之光 ;志而 好学, 如炳烛 之光。 ——刘 向 63、三军可夺帅也,匹夫不可夺志也。 ——孔 丘 64、人生就是学校。在那里,与其说好 的教师 是幸福 ,不如 说好的 教师是 不幸。 ——海 贝尔 65、接受挑战,就可以享受胜利的喜悦 。——杰纳勒 尔·乔治·S·巴顿
谢谢!
ห้องสมุดไป่ตู้

杭电acm初学者课件

杭电acm初学者课件



2006年5月,浙江省第二届“舜宇”杯大学生程序设计大 赛
2006年11~12月,第31届ACM首尔、北京、上海和西安赛 区比赛 今年…
9 2019/5/16


预期赛事(今后每年)

3~4月,举行校内大赛(暨选拔赛) 5月,参加浙江省大学生程序设计大赛 11月,参加ACM/ICPC亚洲区比赛(至 少参加4~5个赛区的比赛) 另外,每学期至少有三次月赛以及适当 的练习赛

26 2019/5/16
Hdoj_1089源代码:
#include <stdio.h> int main() {
int a,b;
while(scanf("%d %d",&a, &b) != EOF) printf("%d\n",a+b);
}
27 2019/5/16
本类输入解决方案:

C语法: while(scanf("%d %d",&a, &b) != EOF) { .... } C++语法: while( cin >> a >> b ) { .... }
4 2019/5/16
我们说的“ACM” 是什么?
5 2019/5/16
ACM/ICPC:
ACM主办的国际大学生程序设计竞赛 (International Collegiate Programming Contest),简称 ACM / ICPC,自从1977年开始至今已经连续举 办31届。其宗旨是提供一个让大学生向IT界展 示自己分析问题和解决问题的能力的绝好机会, 让下一代IT天才可以接触到其今后工作中将要 用到的各种软件。 现在,ACM / ICPC已成为世界各国大学生中最 具影响力的国际计算机赛事。(非官方)

acm程序设计 线段树和间断树

acm程序设计 线段树和间断树

Segment trees and interval treesLecture5Antoine Vigneronantoine.vigneron@jouy.inra.frINRAOutline referencetextbook chapter10D.Mount Lectures13and24segment trees⇒stabbing queries⇒rectangle intersection interval trees⇒improvementhigher dimensionStabbing queries orthogonal range searching:data points,queryrectanglestabbing problem:data rectangles,query pointin one dimensioninput:a set of n intervals,a query point qoutput:the k intervals that contain qin I R da boxb is isothetic iff it can be writtenb=[x1,x 1]×[x2,x 2]×...×[x d,x d]in other words it is axis–parallelinput:a set of n isothetic boxes,a query point qoutput:the k boxes that contain qMotivationin graphics and databases,objects are often stored intheir bounding boxquery:which objects does point x belong to?firstfind objects whose bounding boxes intersect xSegment treesSegmenttreea data structure to store intervals,or segments in I R2allows to answer stabbingqueriesin I R 2:report the segments that intersect a query vertical line lreportedreportedreportedlquery time:O (log n +k)space usage:O (n log n)preprocessing time:O (n log n )Notationslet S=(s1,s2,...s n)be a set of segments in I R2let E be the set of the x–coordinates of the endpoints ofthe segments of Swe assume general position,that is:|E|=2nfirst sort E in increasing orderE={e1<e2<...e2n}AtomicintervalsE splits I R into2n+1atomicintervals:[−∞,e1][e i,e i+1]for i∈{1,2,...2n−1}[e2n,∞]these are the leaves of the segmenttreeInternalnodesthe segment tree T is a balanced binarytree each internal node u with children v and v is associatedwith an interval I u =I v ∪Iv an elementary interval is an interval associated with a node of T (it can be an atomicinterval)I v I vExamplePartitioning asegmentlet s∈S be a segment whose endpoints havex–coordinates e i and ej[e i,e j]is split into several elementaryintervalsthey are chosen as close as possible to theroots is stored in each node associated with these elementaryintervalsStandard listseach node u is associated with a standard list L ulet e i<e j be the x–coordinates of the endpoints of s∈Sthen s is stored in L u iff I u⊂[e i,e j]andI parent(u)⊂[e i,e j](see previous slide and next slide)ExampleAlgorithm ReportStabbing(u,x l) Input:root u of T,x–coordinate of l Output:segments in S that cross l1.if u==NULL2.then return3.output L u4.if x l∈I u.left5.then ReportStabbing(u.left,x l)6.if x l∈I u.right7.then ReportStabbing(u.right,x l)it clearly takes O(k+log n)timeInserting asegmentInsertion in a segment tree Algorithm Insert(u,s)Input:root u of T,segment s.Endpoints of s have x–coordinates x−<x+1.if I u⊂[x−,x+]2.then insert s into L u3.else4.if[x−,x+]∩I u.left=∅5.then Insert(u.left,s)6.if[x−,x+]∩I u.right=∅7.then Insert(u.right,s)Propertys is stored at most twice at each level ofTproof:bycontradictionif s stored at more than2nodes at leveli let u be the leftmost such node,u be therightmost let v be another node at level i containingsu v uv.parentthen I v.parent⊂[x−,x+]so s cannot be stored at vAnalysisproperty of previous slide impliesspace usage:O(n log n)insertion in O(log n)time(similar proof:four nodes atmost are visited at each level)actually space usage isΘ(n log n)(example?)query time:O(k+log n)preprocessingsort endpoints:Θ(n log n)timebuild empty segment tree over these endpoints:O(n)timeinsert n segments into T:O(n log n)timeoverall:Θ(n log n)preprocessing timeRectangle intersectionProblem statementinput:a set B of n isothetic boxes in I R2output:all the intersecting pairs in B2using segment trees,we give an O(n log n+k)timealgorithm when k is the number of intersecting pairs note:this is optimalnote:faster than our line segment intersection algorithmspace usage:Θ(n log n)due to segment treesspace usage is not optimal(O(n)is possible withoptimal query time and preprocessing time)Exampleb 2b 5output:(b 1,b 3),(b 2,b 3),(b 2,b 4),(b 3,b 4)Two kinds ofintersectionsoverlapintersecting edges⇒reduces to intersectionreporting for isotheticsegmentsinclusion we can find them using stabbing queriesReporting overlapsequivalent to reporting intersecting edgesplane sweep approachsweep line status:BBST containing the horizontal linesegments that intersect the sweep line,by increasingy–coordinateseach time a vertical line segment is encountered,reportintersection by range searching in the BBST preprocessing time:O(n log n)for sorting endpointsrunning time:O(k+n log n)Reporting inclusionsstill using plane sweepsweep line status:the boxes that intersect the sweepline l,in a segment tree with respect to y–coordinates the endpoints are the y–coordinates of the horizontaledges of the boxesat a given time,only rectangles that intersect l are inthe segment treewe can perform insertion and deletions in a segmenttree in O(log n)timeeach time a vertex of a box is encountered,perform astabbing query in the segment treeRemarksat each step a box intersection can be reported severaltimesin addition there can be overlap and vertex stabbing abox at the same timeto obtain each intersecting pair only once,make somesimple checks(how?)Interval treesIntroductioninterval trees allow to perform stabbing queries in onedimensionquery time:O(k+log n)preprocessing time:O(n log n)space:O(n)reference:D.Mount notes,page100(vertical linestabbing queries)to page103(not including vertical segment stabbing queries)Preliminarylet x med be the median ofES l:segments of S that are completely to the left of xmedS med:segments of S that contain xmedS r:segments of S that are completely to the right of x medx medS medS rS lData structurerecursive data structureleft child of the root:interval tree storing S lright child of the root:interval tree storing S rat the root of the interval tree,we store S med in two listsM L is sorted according to the coordinate of the leftendpoint(in increasing order)M R is sorted according to the coordinate of the rightendpoint(in decreasing order)Examples 1s 2s 3s 5s 7s 4s 6Interval tree ons 3and s 5Interval tree on M l =(s 4,s 6,s 1)M r =(s 1,s 4,s 6)s 2and s 7Stabbing queriesquery:x q,find the intervals that contain x qif x q<x med thenScan M l in increasing order,and report segmentsthat are stabbed.When x q becomes smaller than the x–coordinate of the current left endpoint,stop.recurse on S lif x q>x medanalogous,but on the right sideAnalysisquery timesize of the subtree divided by at least two at eachlevelscanning through M l or M r:proportional to thenumber of reported intervalsconclusion:O(k+log n)timespace usage:O(n)(each segment is stored in two lists,and the tree is balanced)preprocessing time:easy to do it in O(n log n)timeStabbing queries in higherdimensionApproachin I R d,a set B of n boxesfor a query point qfind all the boxes that contain itwe use a multi–level segment treeinductive definition,induction on dfirst,we store B in a segment tree T with respect tox1–coordinatefor all node u of T,associate a(d−1)–dimensionalmulti–level segment tree over L u,with respect to (x2,x3...x d)Performing queriessearch for q in Tfor all nodes in the search path,query recursively the(d−1)–dimensional multi–level segment treethere are log n such queriesby induction on d,we can prove thatquery time:O(k+log d n)space usage:O(n log d n)preprocessing time:O(n log d n)Improvementsfractional cascading at the deepest level of the tree:gains a factor log n on the query time boundinterval trees at the deepest level:gains log n on the space bound。

浙大ACM简单讲解 1

浙大ACM简单讲解 1
总结比赛经验团队合作角色定位任务分工队长codingdebug一题读两遍赛前准备赛前准备熟悉题目编译器差异vc60编译通过但是在zoj编译出错devc中longlong的输入格式为i64d而zoj中为lld打印功能比赛进行时比赛策略全面开花vs孤注一掷输入输出输出格式如时间02d
Lecture I 比赛经验与编程技巧
– 得到右数第k位值 – 把右数第k位置1 – 把右数第k位取反 – 把最右边的1置0 – 把最右边的0置1 – 判断奇偶(最低位) (x >> k) & 1 x | (1 << k) x ^ (1 << k) x & (x – 1) x | (x + 1) x&1
枚举所有选取方式
• 枚举n个数中选一些的方式
熟悉比赛环境
• 熟悉交题、查看返回信息的方法 • 熟悉Runs中的Search功能 • 打印功能
比赛进行时
比赛策略
• 寻找简单题 • 看题、交流题意 • 观察气球、ranklist,跟风 • 打印、纸上调试 • 学会放弃 • 全面开花 vs 孤注一掷
输入输出
• 几种输入输出要求 • 负数和-1的区别 • 行内拆分(使用stringstream) • 输出格式,如时间”%02d:%02d:%02d”
• 申请新节点,并加到p节点后
– next[p] = ind++;
Standard C++ Library
C++风格头文件
• #include • #include • #include • #include • #include • #include • #include <iostream> <cstdio> <string> <cstring> <cmath> <vector> <algorithm>

浙大ACM简单讲解

浙大ACM简单讲解

• dp[2] = dp[1] + 1 + 1 = 4
• dp[3] = min{ dp[1] + 1 * 2 + 1, dp[2] + 1 + 1}
•
=5
G Islands
• 给定最多100个点的有向图,问有多少种加 边的方式,可以让最后整个图只由一些环 构成,没有多余的边。一个环至少要两个 点。
Lecture III 赛题解析
杭航@ZJU mailto:Hang.Hang.ZJU@
QQ:54621399
Part I The 10th ZJU Programming Contest
概述
• A Clock
472/614
• B CAPTCHA
87/399
• C Runaway t Bulb
• 三分法 • 求单峰函数在(x1,x2)上的极值 • 令a=(x2-x1)/3 + x1 • 令b=(x2-x1)/3 *2 + x1 • 如果f(a)>f(b),则用b更新x2 • 如果f(a)<f(b),则用a更新x1 • 每次把区间缩小成原来的2/3,最后收敛到
B Light Bulb
• 方法一:数学解法,列出函数式子,求导 解决
• 方法二:猜测L是关于某个参数的单峰函数, 可以采用三分法。
B Light Bulb
• 二分法 • 求单调函数在(x1,x2)上的零点 • 令x=(x1+x1)/2 • 如果f(x)和f(x1)同号,则用x更新x1 • 如果f(x)和f(x2)同号,则用x更新x2 • 每次把区间缩小成原来的1/2,最后收敛到
H Break Out
• 预处理后,变成了一个背包问题,背包的 容量最多为200,有最多200个物品,每个 物品不同容量的时候有不同的价值,求使 得总价值最高的方案。

ACM培训资料

ACM培训资料

ACM培训资料目录第一篇入门篇 (3)第1章新手入门 (5)1ACM国际大学生程序设计竞赛简介 (5)2ACM竞赛需要的知识 (8)3团队配合 (14)4练习、练习、再练习 (15)5对新手的一些建议 (16)第2章C++语言介绍 (22)1C++简介 (22)2变量 (23)3C++数据类型 (25)4C++操作符 (30)5数组 (35)6字符数组 (38)7字串操作函数 (41)8过程控制 (45)9C++中的函数 (54)10函数规则 (59)第3章STL简介 (61)1泛型程序设计 (61)2STL 的组成 (67)第二篇算法篇 (102)第1章基本算法 (103)1算法初步 (103)2分治算法 (115)3搜索算法 (124)4贪婪算法 (135)第2章进阶算法 (165)1数论基础 (165)2图论算法 (180)3计算几何基础 (222)第三篇实践篇 (246)第1章《多边形》 (247)第2章《灌溉问题》 (255)第3章《L GAME》 (263)第4章《NUMBER》解题报告 (271)第5章《J OBS》解题报告 (275)第6章《包裹运送》 (283)第7章《桶的摆放》 (290)第一篇入门篇练就坚实的基础,总有一天……我们可以草木皆兵!第1章新手入门1ACM国际大学生程序设计竞赛简介1.1背景与历史1970年在美国TexasA&M大学举办了首次区域竞赛,从而拉开了国际大学生程序设计竞赛的序幕。

1977年,该项竞赛被分为两个级别,即区域赛和总决赛,这便是现代ACM竞赛的开始。

在亚洲、美国、欧洲、太平洋地区均设有区域赛点。

1995至1996年,来自世界各地的一千多支高校的代表队参加了ACM区域竞赛。

ACM 大学生程序设计竞赛由美国计算机协会(ACM)举办,旨在向全世界的大学生提供一个展示和锻炼其解决问题和运用计算机能力的机会,现已成为全世界范围内历史最悠久、规模最大的大学生程序设计竞赛。

ACM 程序设计竞赛入门:第4讲 简单数据结构


2020/12/10
7
1. 并查集
初始状态 : {1} {2} {3} {4} {5} {6} {7} {8} {9}
输入关系 分离集合
(2,4)
{2,4}
•最后我们得到3 个集合{1,2,3,4},
(5,7) (1,3) (8,9) (1,2) (5,6)
{2,4} {5,7} {1,3} {2,4} {5,7} {1,3} {2,4} {5,7} {8,9} {1,2,3,4} {5,7} {8,9} {1,2,3,4} {5,6,7} {8,9}
两个强盗是同一团伙的条件是当且仅当他们是朋 友。现在给你一些关于强盗们的信息,问你最多 有多少个强盗团伙。
2020/12/10
3
1. 并查集
1.1 引例
输入格式 (Input Format):
输入的第一行是一个整数N(2<=N<=1000),表 示强盗的个数(从1编号到N)。 第二行 M(1<=M<=5000),表示关于强盗的信息条数。 以下M行,每行可能是F p q或是E p q(1<=p q<=N),F表示p和q是朋友,E表示p和q是敌人 。输入数据保证不会产生信息的矛盾。
第四讲 简单数据结构
2020/12/10
1
主要内容
并查集 树状数组 线段树
2020/12/10
2
1. 并查集
1.1 引例
题目描述:
1920年的芝加哥,出现了一群强盗。如果两个强 盗遇上了,那么他们要么是朋友,要么是敌人。 而且有一点是肯定的,就是:
我朋友的朋友是我的朋友。
我敌人的敌人也是我的朋友。
效果:任意顺序的合并操作以后,包 含k个节点的树的最大高度不超过lgk

ACM 竞赛培训






河南赛区赛题3

【 样例 】
河南赛区赛题4-枚举





在灾区,多数人已经受伤,缺水,少食物,精神处在崩溃的边缘。很多人的生存条件仅能维持几天。灾民 需要帐篷、衣物、食品和医疗器材、药品等物资。14日上午,中央军委委员、空军司令员许其亮组织召开 空军首长办公会,将空军下一步救灾重点确定为抢救伤员、空投、空运。空军各部队都派出多架运输机, 准备向灾区空运急需物品。 现在已知四种打包过的急需物品重量分别为C1, C2, C3,C4 ,数量分别为M1,M2,M3,M4包。一架运输 机的载重量为W, 现在各部队关心将一架运输机装满共有多少种运载方案,以便调度进行空运。 比如C={ 100, 200, 500, 1000},M={ 3, 2, 3, 1 }, W=1000, 一共有4种运载方案: 1000=100+100+100+200+500 1000=100+200+200+500 1000=500+500 1000=1000 【标准输入】 C1 C2 C3 C4 N 其中 N为空运的部队数 Mi1 Mi2 Mi3 Mi4 Wi 表示各运载部队需空运的4种物品数量Mi 和各自运输机的载重量Wi i=1,2,….. , N
河南赛区赛题2

【样 例】
河南赛区赛题3-排序查找算法

【试题三】 密码破译 某组织欲破获一个外星人的密码,密码由一定长度的字串组成。此组织拥有一些破译此密码 的长度不同的钥匙,若两个钥匙的长度之和恰好为此密码的长度,则此密码被成功破译。现 在就请你编程找出能破译此密码的两个钥匙。 【标准输入】 第一行: N N为钥匙的个数(1<=N<=1000) 第二行: L L为密码的长度 以下有N行: Ai 每一行是一把钥匙的长度 i=1,2,……,N 【标准输出】 若无法找到破译此密码的钥匙,则输出0 若找到两把破译的钥匙,则输出文件有两行,分别为两把钥匙的编号,按从小到大输出。若 有多种破译方案,则只输出包含起始编号最小的一组即可。 [【约束条件】 (1)1<= N,L,Ai <=1000(i=1, 2, ….., N ) (2)时间限制: 1000MS

ACM技术培训文档


VLAN设置 设置
•
802.1Q设置是在VLAN TRUNK环境下使用,如该设备接入到VLAN TRUNK环 境中,那么设备就要让trunk包从设备中通过,此时就要根据两端的VLAN ID分 别设置虚拟子接口,然后在子接口之间设置透明或者路由。 对于非VLAN TRUNK环境,在此不必做任何设置。
认证
• •
如果要用使用认证功能,这里首先要启用认证功能。 认证功能启用后,下一步要将认证网段指定出来,这里很关键,否则无法进 行认证。
认证网段及免认证
•
如果启用认证功能,则这里必须指定需要认证的网段,不在该网段内的用户 无法访问网络。 免认证IP必须在认证网段内,否则不生效。如果加入了免认证,则该用户上 网无限制。 免认证服务器是指启用认证后,对外提供服务的服务器ip不在认证范围内,任 何用户访问该服务器都无需认证。
备份与恢复
• •
•
备份与恢复分为两部分,一部分是备份,一部分是恢复。 这里的备份只能备份网络控制的配置文件,至于审计内容的备份在网络审计的 配置中去实现。同时,配置文件可事先下载保存,同时也支持将配置文件导入 上传的功能。 恢复出厂设置时在这里点击。
数据库表备份
• •
数据库表备份是指网络控制功能的数据库表备份。 备份出来的数据可在“上传/下载”表单里。
报警日志
•
报警日志是在模块规则中设置了阻断、告警等功能,如果有用户行为违反了 这些行为,系统会发出告警,这些告警会记录在这里。因此,阻断和告警是 否生效,可查看这里的报警日志,如果没有,说明该行为没有触发,换句话 是没有生效。
网络接入
• •
在“网络接入”中选择部署模式,以及配置网卡地址和接口类型。 注意:通常只选择内网作为监控模式,其他选择为“管理”即可。接口类型 中有“其他”,是指该接口外联数据库,设备将审计数据发送到外部数据库 。“管理”是指旁路接入时使用该接口进行设备管理。

acm训练资料(浙大模板)

1、几何1.1 注意 (4)1.2 几何公式 (4)1.3 多边形 (6)1.4 多边形切割 (9)1.5 浮点函数 (10)1.6 面积 (15)1.7 球面 (16)1.8 三角形 (17)1.9 三维几何 (19)1.10 凸包 (26)1.11 网格 (28)1.12 圆 (29)1.13 整数函数 (30)2、组合2.1 组合公式 (33)2.2 排列组合生成 (33)2.3 生成gray码 (35)2.4 置换(polya) (35)2.5 字典序全排列 (36)2.6 字典序组合 (36)3、结构3.1 并查集 (37)3.2 堆 (38)3.3 线段树 (39)3.4 子段和 (44)3.5 子阵和 (44)4、数论4.1 阶乘最后非0位 (45)4.2 模线性方程组 (46)4.3 素数 (47)4.4 欧拉函数 (48)5、数值计算5.1 定积分计算(Romberg) (49)5.2 多项式求根(牛顿法) (51)5.3 周期性方程(追赶法) (52)6、图论—NP搜索6.1 最大团 (53)6.2 最大团(n<64)(faster) (54)7、图论—连通性7.1 无向图关键点(dfs邻接阵) (56)7.2 无向图关键边(dfs邻接阵) (57)7.3 无向图的块(bfs邻接阵) (58)7.4 无向图连通分支(dfs/bfs邻接阵) (59)7.5 有向图强连通分支(dfs/bfs邻接阵) (60)7.6 有向图最小点基(邻接阵) (61)8、图论—匹配8.1 二分图最大匹配(hungary邻接表) (62)8.2 二分图最大匹配(hungary邻接阵) (63)8.3 二分图最大匹配(hungary正向表) (63)8.4二分图最佳匹配(kuhn_munkras邻接阵) (64)8.5 一般图匹配(邻接表) (65)8.6 一般图匹配(邻接阵) (66)8.7 一般图匹配(正向表) (66)9、图论—网络流9.1 最大流(邻接阵) (67)9.2 上下界最大流(邻接阵) (68)9.3 上下界最小流(邻接阵) (69)9.4 最大流无流量(邻接阵) (70)9.5 最小费用最大流(邻接阵) (70)10、图论—应用10.1 欧拉回路(邻接阵) (71)10.2 树的前序表转化 (72)10.3 树的优化算法 (73)10.4 拓扑排序(邻接阵) (74)10.5 最佳边割集 (75)10.6 最佳点割集 (76)10.7 最小边割集 (77)10.8 最小点割集 (78)10.9 最小路径覆盖 (80)11、图论—支撑树11.1 最小生成树(kruskal邻接表) (80)11.2 最小生成树(kruskal正向表) (82)11.3 最小生成树(prim+binary_heap邻接表) (83)11.4 最小生成树(prim+binary_heap正向表) (84)11.5 最小生成树(prim+mapped_heap邻接表) (85)11.6 最小生成树(prim+mapped_heap正向表) (87)11.7 最小生成树(prim邻接阵) (88)11.8 最小树形图(邻接阵) (88)12、图论—最短路径12.1 最短路径(单源bellman_ford邻接阵) (90)12.2 最短路径(单源dijkstra+bfs邻接表) (90)12.3 最短路径(单源dijkstra+bfs正向表) (91)12.4 最短路径(单源dijkstra+binary_heap邻接表) (92)12.5 最短路径(单源dijkstra+binary_heap正向表) (93)12.6 最短路径(单源dijkstra+mapped_heap邻接表) (94)12.7 最短路径(单源dijkstra+mapped_heap正向表) (95)12.8 最短路径(单源dijkstra邻接阵) (96)12.9 最短路径(多源floyd_warshall邻接阵) (97)13、应用13.1 Joseph问题 (97)13.2 N皇后构造解 (98)13.3 布尔母函数 (99)13.4 第k元素 (99)13.5 幻方构造 (100)13.6 模式匹配(kmp) (101)13.7 逆序对数 (102)13.8 字符串最小表示 (102)13.9 最长公共单调子序列 (103)13.10 最长子序列 (104)13.11 最大子串匹配 (105)13.12 最大子段和 (106)13.13 最大子阵和 (106)14、其它14.1 大数(只能处理正数) (107)14.2 分数 (113)14.3 矩阵 (115)14.4 线性方程组 (117)14.5 线性相关 (119)14.6 日期 (120)1、几何1.1注意1. 注意舍入方式(0.5的舍入方向);防止输出-0.2. 几何题注意多测试不对称数据.3. 整数几何注意xmult和dmult是否会出界;符点几何注意eps的使用.4. 避免使用斜率;注意除数是否会为0.5. 公式一定要化简后再代入.6. 判断同一个2*PI域内两角度差应该是abs(a1-a2)<beta||abs(a1-a2)>pi+pi-beta;相等应该是abs(a1-a2)<eps||abs(a1-a2)>pi+pi-eps;7. 需要的话尽量使用atan2,注意:atan2(0,0)=0,atan2(1,0)=pi/2,atan2(-1,0)=-pi/2,atan2(0,1)=0,atan2(0,-1)=pi.8. cross product = |u|*|v|*sin(a)dot product = |u|*|v|*cos(a)9. (P1-P0)x(P2-P0)结果的意义:正: <P0,P1>在<P0,P2>顺时针(0,pi)内负: <P0,P1>在<P0,P2>逆时针(0,pi)内0 : <P0,P1>,<P0,P2>共线,夹角为0或pi10. 误差限缺省使用1e-8!1.2几何公式三角形:1. 半周长P=(a+b+c)/22. 面积S=aHa/2=absin(C)/2=sqrt(P(P-a)(P-b)(P-c))3. 中线Ma=sqrt(2(b^2+c^2)-a^2)/2=sqrt(b^2+c^2+2bccos(A))/24. 角平分线Ta=sqrt(bc((b+c)^2-a^2))/(b+c)=2bccos(A/2)/(b+c)5. 高线Ha=bsin(C)=csin(B)=sqrt(b^2-((a^2+b^2-c^2)/(2a))^2)6. 内切圆半径r=S/P=asin(B/2)sin(C/2)/sin((B+C)/2)=4Rsin(A/2)sin(B/2)sin(C/2)=sqrt((P-a)(P-b)(P-c)/P)=Ptan(A/2)tan(B/2)tan(C/2)7. 外接圆半径R=abc/(4S)=a/(2sin(A))=b/(2sin(B))=c/(2sin(C))四边形:D1,D2为对角线,M对角线中点连线,A为对角线夹角1. a^2+b^2+c^2+d^2=D1^2+D2^2+4M^22. S=D1D2sin(A)/2(以下对圆的内接四边形)3. ac+bd=D1D24. S=sqrt((P-a)(P-b)(P-c)(P-d)),P为半周长正n边形:R为外接圆半径,r为内切圆半径1. 中心角A=2PI/n2. 内角C=(n-2)PI/n3. 边长a=2sqrt(R^2-r^2)=2Rsin(A/2)=2rtan(A/2)4. 面积S=nar/2=nr^2tan(A/2)=nR^2sin(A)/2=na^2/(4tan(A/2))圆:1. 弧长l=rA2. 弦长a=2sqrt(2hr-h^2)=2rsin(A/2)3. 弓形高h=r-sqrt(r^2-a^2/4)=r(1-cos(A/2))=atan(A/4)/24. 扇形面积S1=rl/2=r^2A/25. 弓形面积S2=(rl-a(r-h))/2=r^2(A-sin(A))/2棱柱:1. 体积V=Ah,A为底面积,h为高2. 侧面积S=lp,l为棱长,p为直截面周长3. 全面积T=S+2A棱锥:1. 体积V=Ah/3,A为底面积,h为高(以下对正棱锥)2. 侧面积S=lp/2,l为斜高,p为底面周长3. 全面积T=S+A棱台:1. 体积V=(A1+A2+sqrt(A1A2))h/3,A1.A2为上下底面积,h为高(以下为正棱台)2. 侧面积S=(p1+p2)l/2,p1.p2为上下底面周长,l为斜高3. 全面积T=S+A1+A2圆柱:1. 侧面积S=2PIrh2. 全面积T=2PIr(h+r)3. 体积V=PIr^2h圆锥:1. 母线l=sqrt(h^2+r^2)2. 侧面积S=PIrl3. 全面积T=PIr(l+r)4. 体积V=PIr^2h/3圆台:1. 母线l=sqrt(h^2+(r1-r2)^2)2. 侧面积S=PI(r1+r2)l3. 全面积T=PIr1(l+r1)+PIr2(l+r2)4. 体积V=PI(r1^2+r2^2+r1r2)h/3球:1. 全面积T=4PIr^22. 体积V=4PIr^3/3球台:1. 侧面积S=2PIrh2. 全面积T=PI(2rh+r1^2+r2^2)3. 体积V=PIh(3(r1^2+r2^2)+h^2)/6球扇形:1. 全面积T=PIr(2h+r0),h为球冠高,r0为球冠底面半径2. 体积V=2PIr^2h/31.3多边形#include <stdlib.h>#include <math.h>#define MAXN 1000#define offset 10000#define eps 1e-8#define zero(x) (((x)>0?(x):-(x))<eps)#define _sign(x) ((x)>eps?1:((x)<-eps?2:0))struct point{double x,y;};struct line{point a,b;};double xmult(point p1,point p2,point p0){return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);}//判定凸多边形,顶点按顺时针或逆时针给出,允许相邻边共线int is_convex(int n,point* p){int i,s[3]={1,1,1};for (i=0;i<n&&s[1]|s[2];i++)s[_sign(xmult(p[(i+1)%n],p[(i+2)%n],p[i]))]=0;return s[1]|s[2];}//判定凸多边形,顶点按顺时针或逆时针给出,不允许相邻边共线int is_convex_v2(int n,point* p){int i,s[3]={1,1,1};for (i=0;i<n&&s[0]&&s[1]|s[2];i++)s[_sign(xmult(p[(i+1)%n],p[(i+2)%n],p[i]))]=0;return s[0]&&s[1]|s[2];}//判点在凸多边形内或多边形边上,顶点按顺时针或逆时针给出int inside_convex(point q,int n,point* p){int i,s[3]={1,1,1};for (i=0;i<n&&s[1]|s[2];i++)s[_sign(xmult(p[(i+1)%n],q,p[i]))]=0;return s[1]|s[2];}//判点在凸多边形内,顶点按顺时针或逆时针给出,在多边形边上返回0int inside_convex_v2(point q,int n,point* p){int i,s[3]={1,1,1};for (i=0;i<n&&s[0]&&s[1]|s[2];i++)s[_sign(xmult(p[(i+1)%n],q,p[i]))]=0;return s[0]&&s[1]|s[2];}//判点在任意多边形内,顶点按顺时针或逆时针给出//on_edge表示点在多边形边上时的返回值,offset为多边形坐标上限int inside_polygon(point q,int n,point* p,int on_edge=1){point q2;int i=0,count;while (i<n)for (count=i=0,q2.x=rand()+offset,q2.y=rand()+offset;i<n;i++)if(zero(xmult(q,p[i],p[(i+1)%n]))&&(p[i].x-q.x)*(p[(i+1)%n].x-q.x)<eps&&(p[i].y-q.y)*(p[(i+1)% n].y-q.y)<eps)return on_edge;else if (zero(xmult(q,q2,p[i])))break;else if (xmult(q,p[i],q2)*xmult(q,p[(i+1)%n],q2)<-eps&&xmult(p[i],q,p[(i+1)%n])*xmult(p[i],q2,p[(i+1) %n])<-eps)count++;return count&1;}inline int opposite_side(point p1,point p2,point l1,point l2){return xmult(l1,p1,l2)*xmult(l1,p2,l2)<-eps;}inline int dot_online_in(point p,point l1,point l2){return zero(xmult(p,l1,l2))&&(l1.x-p.x)*(l2.x-p.x)<eps&&(l1.y-p.y)*(l2.y-p.y)<eps;}//判线段在任意多边形内,顶点按顺时针或逆时针给出,与边界相交返回1int inside_polygon(point l1,point l2,int n,point* p){point t[MAXN],tt;int i,j,k=0;if (!inside_polygon(l1,n,p)||!inside_polygon(l2,n,p))return 0;for (i=0;i<n;i++)if (opposite_side(l1,l2,p[i],p[(i+1)%n])&&opposite_side(p[i],p[(i+1)%n],l1,l2)) return 0;else if (dot_online_in(l1,p[i],p[(i+1)%n]))t[k++]=l1;else if (dot_online_in(l2,p[i],p[(i+1)%n]))t[k++]=l2;else if (dot_online_in(p[i],l1,l2))t[k++]=p[i];for (i=0;i<k;i++)for (j=i+1;j<k;j++){tt.x=(t[i].x+t[j].x)/2;tt.y=(t[i].y+t[j].y)/2;if (!inside_polygon(tt,n,p))return 0;}return 1;}point intersection(line u,line v){point ret=u.a;double t=((u.a.x-v.a.x)*(v.a.y-v.b.y)-(u.a.y-v.a.y)*(v.a.x-v.b.x)) /((u.a.x-u.b.x)*(v.a.y-v.b.y)-(u.a.y-u.b.y)*(v.a.x-v.b.x));ret.x+=(u.b.x-u.a.x)*t;ret.y+=(u.b.y-u.a.y)*t;return ret;}point barycenter(point a,point b,point c){line u,v;u.a.x=(a.x+b.x)/2;u.a.y=(a.y+b.y)/2;u.b=c;v.a.x=(a.x+c.x)/2;v.a.y=(a.y+c.y)/2;v.b=b;return intersection(u,v);}//多边形重心point barycenter(int n,point* p){point ret,t;double t1=0,t2;int i;ret.x=ret.y=0;for (i=1;i<n-1;i++)if (fabs(t2=xmult(p[0],p[i],p[i+1]))>eps){t=barycenter(p[0],p[i],p[i+1]);ret.x+=t.x*t2;ret.y+=t.y*t2;t1+=t2;}if (fabs(t1)>eps)ret.x/=t1,ret.y/=t1;return ret;}1.4多边形切割//多边形切割//可用于半平面交#define MAXN 100#define eps 1e-8#define zero(x) (((x)>0?(x):-(x))<eps)struct point{double x,y;};double xmult(point p1,point p2,point p0){return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);}int same_side(point p1,point p2,point l1,point l2){return xmult(l1,p1,l2)*xmult(l1,p2,l2)>eps;}point intersection(point u1,point u2,point v1,point v2){point ret=u1;double t=((u1.x-v1.x)*(v1.y-v2.y)-(u1.y-v1.y)*(v1.x-v2.x))/((u1.x-u2.x)*(v1.y-v2.y)-(u1.y-u2.y)*(v1.x-v2.x));ret.x+=(u2.x-u1.x)*t;ret.y+=(u2.y-u1.y)*t;return ret;}//将多边形沿l1,l2确定的直线切割在side侧切割,保证l1,l2,side不共线void polygon_cut(int& n,point* p,point l1,point l2,point side){point pp[100];int m=0,i;for (i=0;i<n;i++){if (same_side(p[i],side,l1,l2))pp[m++]=p[i];if(!same_side(p[i],p[(i+1)%n],l1,l2)&&!(zero(xmult(p[i],l1,l2))&&zero(xmult(p[(i+1)%n],l1,l2)))) pp[m++]=intersection(p[i],p[(i+1)%n],l1,l2);}for (n=i=0;i<m;i++)if (!i||!zero(pp[i].x-pp[i-1].x)||!zero(pp[i].y-pp[i-1].y))p[n++]=pp[i];if (zero(p[n-1].x-p[0].x)&&zero(p[n-1].y-p[0].y))n--;if (n<3)n=0;}1.5浮点函数//浮点几何函数库#include <math.h>#define eps 1e-8#define zero(x) (((x)>0?(x):-(x))<eps)struct point{double x,y;};struct line{point a,b;};//计算cross product (P1-P0)x(P2-P0)double xmult(point p1,point p2,point p0){return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);}double xmult(double x1,double y1,double x2,double y2,double x0,double y0){ return (x1-x0)*(y2-y0)-(x2-x0)*(y1-y0);}//计算dot product (P1-P0).(P2-P0)double dmult(point p1,point p2,point p0){return (p1.x-p0.x)*(p2.x-p0.x)+(p1.y-p0.y)*(p2.y-p0.y);}double dmult(double x1,double y1,double x2,double y2,double x0,double y0){ return (x1-x0)*(x2-x0)+(y1-y0)*(y2-y0);}//两点距离double distance(point p1,point p2){return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));}double distance(double x1,double y1,double x2,double y2){return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));}//判三点共线int dots_inline(point p1,point p2,point p3){return zero(xmult(p1,p2,p3));}int dots_inline(double x1,double y1,double x2,double y2,double x3,double y3){ return zero(xmult(x1,y1,x2,y2,x3,y3));}//判点是否在线段上,包括端点int dot_online_in(point p,line l){return zero(xmult(p,l.a,l.b))&&(l.a.x-p.x)*(l.b.x-p.x)<eps&&(l.a.y-p.y)*(l.b.y-p.y)<eps; }int dot_online_in(point p,point l1,point l2){return zero(xmult(p,l1,l2))&&(l1.x-p.x)*(l2.x-p.x)<eps&&(l1.y-p.y)*(l2.y-p.y)<eps;}int dot_online_in(double x,double y,double x1,double y1,double x2,double y2){return zero(xmult(x,y,x1,y1,x2,y2))&&(x1-x)*(x2-x)<eps&&(y1-y)*(y2-y)<eps;}//判点是否在线段上,不包括端点int dot_online_ex(point p,line l){returndot_online_in(p,l)&&(!zero(p.x-l.a.x)||!zero(p.y-l.a.y))&&(!zero(p.x-l.b.x)||!zero(p.y-l.b.y)); }int dot_online_ex(point p,point l1,point l2){returndot_online_in(p,l1,l2)&&(!zero(p.x-l1.x)||!zero(p.y-l1.y))&&(!zero(p.x-l2.x)||!zero(p.y-l2.y)); }int dot_online_ex(double x,double y,double x1,double y1,double x2,double y2){ returndot_online_in(x,y,x1,y1,x2,y2)&&(!zero(x-x1)||!zero(y-y1))&&(!zero(x-x2)||!zero(y-y2));}//判两点在线段同侧,点在线段上返回0int same_side(point p1,point p2,line l){return xmult(l.a,p1,l.b)*xmult(l.a,p2,l.b)>eps;}int same_side(point p1,point p2,point l1,point l2){return xmult(l1,p1,l2)*xmult(l1,p2,l2)>eps;}//判两点在线段异侧,点在线段上返回0int opposite_side(point p1,point p2,line l){return xmult(l.a,p1,l.b)*xmult(l.a,p2,l.b)<-eps;}int opposite_side(point p1,point p2,point l1,point l2){return xmult(l1,p1,l2)*xmult(l1,p2,l2)<-eps;}//判两直线平行int parallel(line u,line v){return zero((u.a.x-u.b.x)*(v.a.y-v.b.y)-(v.a.x-v.b.x)*(u.a.y-u.b.y));}int parallel(point u1,point u2,point v1,point v2){return zero((u1.x-u2.x)*(v1.y-v2.y)-(v1.x-v2.x)*(u1.y-u2.y));}//判两直线垂直int perpendicular(line u,line v){return zero((u.a.x-u.b.x)*(v.a.x-v.b.x)+(u.a.y-u.b.y)*(v.a.y-v.b.y));int perpendicular(point u1,point u2,point v1,point v2){return zero((u1.x-u2.x)*(v1.x-v2.x)+(u1.y-u2.y)*(v1.y-v2.y));}//判两线段相交,包括端点和部分重合int intersect_in(line u,line v){if (!dots_inline(u.a,u.b,v.a)||!dots_inline(u.a,u.b,v.b))return !same_side(u.a,u.b,v)&&!same_side(v.a,v.b,u);return dot_online_in(u.a,v)||dot_online_in(u.b,v)||dot_online_in(v.a,u)||dot_online_in(v.b,u); }int intersect_in(point u1,point u2,point v1,point v2){if (!dots_inline(u1,u2,v1)||!dots_inline(u1,u2,v2))return !same_side(u1,u2,v1,v2)&&!same_side(v1,v2,u1,u2);returndot_online_in(u1,v1,v2)||dot_online_in(u2,v1,v2)||dot_online_in(v1,u1,u2)||dot_online_in(v2,u1,u 2);}//判两线段相交,不包括端点和部分重合int intersect_ex(line u,line v){return opposite_side(u.a,u.b,v)&&opposite_side(v.a,v.b,u);}int intersect_ex(point u1,point u2,point v1,point v2){return opposite_side(u1,u2,v1,v2)&&opposite_side(v1,v2,u1,u2);}//计算两直线交点,注意事先判断直线是否平行!//线段交点请另外判线段相交(同时还是要判断是否平行!)point intersection(line u,line v){point ret=u.a;double t=((u.a.x-v.a.x)*(v.a.y-v.b.y)-(u.a.y-v.a.y)*(v.a.x-v.b.x))/((u.a.x-u.b.x)*(v.a.y-v.b.y)-(u.a.y-u.b.y)*(v.a.x-v.b.x));ret.x+=(u.b.x-u.a.x)*t;ret.y+=(u.b.y-u.a.y)*t;return ret;}point intersection(point u1,point u2,point v1,point v2){point ret=u1;double t=((u1.x-v1.x)*(v1.y-v2.y)-(u1.y-v1.y)*(v1.x-v2.x))/((u1.x-u2.x)*(v1.y-v2.y)-(u1.y-u2.y)*(v1.x-v2.x));ret.x+=(u2.x-u1.x)*t;ret.y+=(u2.y-u1.y)*t;return ret;//点到直线上的最近点point ptoline(point p,line l){point t=p;t.x+=l.a.y-l.b.y,t.y+=l.b.x-l.a.x;return intersection(p,t,l.a,l.b);}point ptoline(point p,point l1,point l2){point t=p;t.x+=l1.y-l2.y,t.y+=l2.x-l1.x;return intersection(p,t,l1,l2);}//点到直线距离double disptoline(point p,line l){return fabs(xmult(p,l.a,l.b))/distance(l.a,l.b);}double disptoline(point p,point l1,point l2){return fabs(xmult(p,l1,l2))/distance(l1,l2);}double disptoline(double x,double y,double x1,double y1,double x2,double y2){ return fabs(xmult(x,y,x1,y1,x2,y2))/distance(x1,y1,x2,y2);}//点到线段上的最近点point ptoseg(point p,line l){point t=p;t.x+=l.a.y-l.b.y,t.y+=l.b.x-l.a.x;if (xmult(l.a,t,p)*xmult(l.b,t,p)>eps)return distance(p,l.a)<distance(p,l.b)?l.a:l.b;return intersection(p,t,l.a,l.b);}point ptoseg(point p,point l1,point l2){point t=p;t.x+=l1.y-l2.y,t.y+=l2.x-l1.x;if (xmult(l1,t,p)*xmult(l2,t,p)>eps)return distance(p,l1)<distance(p,l2)?l1:l2;return intersection(p,t,l1,l2);}//点到线段距离double disptoseg(point p,line l){point t=p;t.x+=l.a.y-l.b.y,t.y+=l.b.x-l.a.x;if (xmult(l.a,t,p)*xmult(l.b,t,p)>eps)return distance(p,l.a)<distance(p,l.b)?distance(p,l.a):distance(p,l.b);return fabs(xmult(p,l.a,l.b))/distance(l.a,l.b);}double disptoseg(point p,point l1,point l2){point t=p;t.x+=l1.y-l2.y,t.y+=l2.x-l1.x;if (xmult(l1,t,p)*xmult(l2,t,p)>eps)return distance(p,l1)<distance(p,l2)?distance(p,l1):distance(p,l2);return fabs(xmult(p,l1,l2))/distance(l1,l2);}//矢量V以P为顶点逆时针旋转angle并放大scale倍point rotate(point v,point p,double angle,double scale){point ret=p;v.x-=p.x,v.y-=p.y;p.x=scale*cos(angle);p.y=scale*sin(angle);ret.x+=v.x*p.x-v.y*p.y;ret.y+=v.x*p.y+v.y*p.x;return ret;}1.6面积#include <math.h>struct point{double x,y;};//计算cross product (P1-P0)x(P2-P0)double xmult(point p1,point p2,point p0){return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);}double xmult(double x1,double y1,double x2,double y2,double x0,double y0){ return (x1-x0)*(y2-y0)-(x2-x0)*(y1-y0);}//计算三角形面积,输入三顶点double area_triangle(point p1,point p2,point p3){return fabs(xmult(p1,p2,p3))/2;}double area_triangle(double x1,double y1,double x2,double y2,double x3,double y3){ return fabs(xmult(x1,y1,x2,y2,x3,y3))/2;}//计算三角形面积,输入三边长double area_triangle(double a,double b,double c){double s=(a+b+c)/2;return sqrt(s*(s-a)*(s-b)*(s-c));}//计算多边形面积,顶点按顺时针或逆时针给出double area_polygon(int n,point* p){double s1=0,s2=0;int i;for (i=0;i<n;i++)s1+=p[(i+1)%n].y*p[i].x,s2+=p[(i+1)%n].y*p[(i+2)%n].x;return fabs(s1-s2)/2;}1.7球面#include <math.h>const double pi=acos(-1);//计算圆心角lat表示纬度,-90<=w<=90,lng表示经度//返回两点所在大圆劣弧对应圆心角,0<=angle<=pidouble angle(double lng1,double lat1,double lng2,double lat2){ double dlng=fabs(lng1-lng2)*pi/180;while (dlng>=pi+pi)dlng-=pi+pi;if (dlng>pi)dlng=pi+pi-dlng;lat1*=pi/180,lat2*=pi/180;return acos(cos(lat1)*cos(lat2)*cos(dlng)+sin(lat1)*sin(lat2));}//计算距离,r为球半径double line_dist(double r,double lng1,double lat1,double lng2,double lat2){ double dlng=fabs(lng1-lng2)*pi/180;while (dlng>=pi+pi)dlng-=pi+pi;if (dlng>pi)dlng=pi+pi-dlng;lat1*=pi/180,lat2*=pi/180;return r*sqrt(2-2*(cos(lat1)*cos(lat2)*cos(dlng)+sin(lat1)*sin(lat2))); }//计算球面距离,r为球半径inline double sphere_dist(double r,double lng1,double lat1,double lng2,double lat2){ return r*angle(lng1,lat1,lng2,lat2);}1.8三角形#include <math.h>struct point{double x,y;};struct line{point a,b;};double distance(point p1,point p2){return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));}point intersection(line u,line v){point ret=u.a;double t=((u.a.x-v.a.x)*(v.a.y-v.b.y)-(u.a.y-v.a.y)*(v.a.x-v.b.x))/((u.a.x-u.b.x)*(v.a.y-v.b.y)-(u.a.y-u.b.y)*(v.a.x-v.b.x));ret.x+=(u.b.x-u.a.x)*t;ret.y+=(u.b.y-u.a.y)*t;return ret;}//外心point circumcenter(point a,point b,point c){line u,v;u.a.x=(a.x+b.x)/2;u.a.y=(a.y+b.y)/2;u.b.x=u.a.x-a.y+b.y;u.b.y=u.a.y+a.x-b.x;v.a.x=(a.x+c.x)/2;v.a.y=(a.y+c.y)/2;v.b.x=v.a.x-a.y+c.y;v.b.y=v.a.y+a.x-c.x;return intersection(u,v);}//内心point incenter(point a,point b,point c){line u,v;double m,n;u.a=a;m=atan2(b.y-a.y,b.x-a.x);n=atan2(c.y-a.y,c.x-a.x);u.b.x=u.a.x+cos((m+n)/2);u.b.y=u.a.y+sin((m+n)/2);v.a=b;m=atan2(a.y-b.y,a.x-b.x);n=atan2(c.y-b.y,c.x-b.x);v.b.x=v.a.x+cos((m+n)/2);v.b.y=v.a.y+sin((m+n)/2);return intersection(u,v);}//垂心point perpencenter(point a,point b,point c){line u,v;u.a=c;u.b.x=u.a.x-a.y+b.y;u.b.y=u.a.y+a.x-b.x;v.a=b;v.b.x=v.a.x-a.y+c.y;v.b.y=v.a.y+a.x-c.x;return intersection(u,v);}//重心//到三角形三顶点距离的平方和最小的点//三角形内到三边距离之积最大的点point barycenter(point a,point b,point c){line u,v;u.a.x=(a.x+b.x)/2;u.a.y=(a.y+b.y)/2;u.b=c;v.a.x=(a.x+c.x)/2;v.a.y=(a.y+c.y)/2;v.b=b;return intersection(u,v);}//费马点//到三角形三顶点距离之和最小的点point fermentpoint(point a,point b,point c){point u,v;double step=fabs(a.x)+fabs(a.y)+fabs(b.x)+fabs(b.y)+fabs(c.x)+fabs(c.y);int i,j,k;u.x=(a.x+b.x+c.x)/3;u.y=(a.y+b.y+c.y)/3;while (step>1e-10)for (k=0;k<10;step/=2,k++)for (i=-1;i<=1;i++)for (j=-1;j<=1;j++){v.x=u.x+step*i;v.y=u.y+step*j;if(distance(u,a)+distance(u,b)+distance(u,c)>distance(v,a)+distance(v,b)+distance(v,c))u=v;}return u;}1.9三维几何//三维几何函数库#include <math.h>#define eps 1e-8#define zero(x) (((x)>0?(x):-(x))<eps)struct point3{double x,y,z;};struct line3{point3 a,b;};struct plane3{point3 a,b,c;};//计算cross product U x Vpoint3 xmult(point3 u,point3 v){point3 ret;ret.x=u.y*v.z-v.y*u.z;ret.y=u.z*v.x-u.x*v.z;ret.z=u.x*v.y-u.y*v.x;return ret;}//计算dot product U . Vdouble dmult(point3 u,point3 v){return u.x*v.x+u.y*v.y+u.z*v.z;}//矢量差U - Vpoint3 subt(point3 u,point3 v){point3 ret;ret.x=u.x-v.x;ret.y=u.y-v.y;ret.z=u.z-v.z;return ret;}//取平面法向量point3 pvec(plane3 s){return xmult(subt(s.a,s.b),subt(s.b,s.c));}point3 pvec(point3 s1,point3 s2,point3 s3){return xmult(subt(s1,s2),subt(s2,s3));}//两点距离,单参数取向量大小double distance(point3 p1,point3 p2){return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)+(p1.z-p2.z)*(p1.z-p2.z)); }//向量大小double vlen(point3 p){return sqrt(p.x*p.x+p.y*p.y+p.z*p.z);}//判三点共线int dots_inline(point3 p1,point3 p2,point3 p3){return vlen(xmult(subt(p1,p2),subt(p2,p3)))<eps;}//判四点共面int dots_onplane(point3 a,point3 b,point3 c,point3 d){return zero(dmult(pvec(a,b,c),subt(d,a)));}//判点是否在线段上,包括端点和共线int dot_online_in(point3 p,line3 l){return zero(vlen(xmult(subt(p,l.a),subt(p,l.b))))&&(l.a.x-p.x)*(l.b.x-p.x)<eps&& (l.a.y-p.y)*(l.b.y-p.y)<eps&&(l.a.z-p.z)*(l.b.z-p.z)<eps;}int dot_online_in(point3 p,point3 l1,point3 l2){return zero(vlen(xmult(subt(p,l1),subt(p,l2))))&&(l1.x-p.x)*(l2.x-p.x)<eps&& (l1.y-p.y)*(l2.y-p.y)<eps&&(l1.z-p.z)*(l2.z-p.z)<eps;}//判点是否在线段上,不包括端点int dot_online_ex(point3 p,line3 l){return dot_online_in(p,l)&&(!zero(p.x-l.a.x)||!zero(p.y-l.a.y)||!zero(p.z-l.a.z))&&(!zero(p.x-l.b.x)||!zero(p.y-l.b.y)||!zero(p.z-l.b.z));}int dot_online_ex(point3 p,point3 l1,point3 l2){return dot_online_in(p,l1,l2)&&(!zero(p.x-l1.x)||!zero(p.y-l1.y)||!zero(p.z-l1.z))&& (!zero(p.x-l2.x)||!zero(p.y-l2.y)||!zero(p.z-l2.z));}//判点是否在空间三角形上,包括边界,三点共线无意义int dot_inplane_in(point3 p,plane3 s){return zero(vlen(xmult(subt(s.a,s.b),subt(s.a,s.c)))-vlen(xmult(subt(p,s.a),subt(p,s.b)))- vlen(xmult(subt(p,s.b),subt(p,s.c)))-vlen(xmult(subt(p,s.c),subt(p,s.a))));}int dot_inplane_in(point3 p,point3 s1,point3 s2,point3 s3){return zero(vlen(xmult(subt(s1,s2),subt(s1,s3)))-vlen(xmult(subt(p,s1),subt(p,s2)))- vlen(xmult(subt(p,s2),subt(p,s3)))-vlen(xmult(subt(p,s3),subt(p,s1))));}//判点是否在空间三角形上,不包括边界,三点共线无意义int dot_inplane_ex(point3 p,plane3 s){return dot_inplane_in(p,s)&&vlen(xmult(subt(p,s.a),subt(p,s.b)))>eps&&vlen(xmult(subt(p,s.b),subt(p,s.c)))>eps&&vlen(xmult(subt(p,s.c),subt(p,s.a)))>eps; }int dot_inplane_ex(point3 p,point3 s1,point3 s2,point3 s3){return dot_inplane_in(p,s1,s2,s3)&&vlen(xmult(subt(p,s1),subt(p,s2)))>eps&& vlen(xmult(subt(p,s2),subt(p,s3)))>eps&&vlen(xmult(subt(p,s3),subt(p,s1)))>eps; }//判两点在线段同侧,点在线段上返回0,不共面无意义int same_side(point3 p1,point3 p2,line3 l){return dmult(xmult(subt(l.a,l.b),subt(p1,l.b)),xmult(subt(l.a,l.b),subt(p2,l.b)))>eps;}int same_side(point3 p1,point3 p2,point3 l1,point3 l2){return dmult(xmult(subt(l1,l2),subt(p1,l2)),xmult(subt(l1,l2),subt(p2,l2)))>eps;}//判两点在线段异侧,点在线段上返回0,不共面无意义int opposite_side(point3 p1,point3 p2,line3 l){return dmult(xmult(subt(l.a,l.b),subt(p1,l.b)),xmult(subt(l.a,l.b),subt(p2,l.b)))<-eps;}int opposite_side(point3 p1,point3 p2,point3 l1,point3 l2){return dmult(xmult(subt(l1,l2),subt(p1,l2)),xmult(subt(l1,l2),subt(p2,l2)))<-eps;}//判两点在平面同侧,点在平面上返回0int same_side(point3 p1,point3 p2,plane3 s){return dmult(pvec(s),subt(p1,s.a))*dmult(pvec(s),subt(p2,s.a))>eps;}int same_side(point3 p1,point3 p2,point3 s1,point3 s2,point3 s3){return dmult(pvec(s1,s2,s3),subt(p1,s1))*dmult(pvec(s1,s2,s3),subt(p2,s1))>eps; }//判两点在平面异侧,点在平面上返回0int opposite_side(point3 p1,point3 p2,plane3 s){return dmult(pvec(s),subt(p1,s.a))*dmult(pvec(s),subt(p2,s.a))<-eps;}int opposite_side(point3 p1,point3 p2,point3 s1,point3 s2,point3 s3){return dmult(pvec(s1,s2,s3),subt(p1,s1))*dmult(pvec(s1,s2,s3),subt(p2,s1))<-eps; }//判两直线平行int parallel(line3 u,line3 v){return vlen(xmult(subt(u.a,u.b),subt(v.a,v.b)))<eps;}int parallel(point3 u1,point3 u2,point3 v1,point3 v2){return vlen(xmult(subt(u1,u2),subt(v1,v2)))<eps;}//判两平面平行int parallel(plane3 u,plane3 v){return vlen(xmult(pvec(u),pvec(v)))<eps;}int parallel(point3 u1,point3 u2,point3 u3,point3 v1,point3 v2,point3 v3){ return vlen(xmult(pvec(u1,u2,u3),pvec(v1,v2,v3)))<eps;}//判直线与平面平行int parallel(line3 l,plane3 s){return zero(dmult(subt(l.a,l.b),pvec(s)));}int parallel(point3 l1,point3 l2,point3 s1,point3 s2,point3 s3){return zero(dmult(subt(l1,l2),pvec(s1,s2,s3)));}//判两直线垂直int perpendicular(line3 u,line3 v){return zero(dmult(subt(u.a,u.b),subt(v.a,v.b)));}int perpendicular(point3 u1,point3 u2,point3 v1,point3 v2){return zero(dmult(subt(u1,u2),subt(v1,v2)));}//判两平面垂直int perpendicular(plane3 u,plane3 v){return zero(dmult(pvec(u),pvec(v)));}int perpendicular(point3 u1,point3 u2,point3 u3,point3 v1,point3 v2,point3 v3){ return zero(dmult(pvec(u1,u2,u3),pvec(v1,v2,v3)));}//判直线与平面平行int perpendicular(line3 l,plane3 s){return vlen(xmult(subt(l.a,l.b),pvec(s)))<eps;}int perpendicular(point3 l1,point3 l2,point3 s1,point3 s2,point3 s3){return vlen(xmult(subt(l1,l2),pvec(s1,s2,s3)))<eps;}//判两线段相交,包括端点和部分重合int intersect_in(line3 u,line3 v){if (!dots_onplane(u.a,u.b,v.a,v.b))return 0;if (!dots_inline(u.a,u.b,v.a)||!dots_inline(u.a,u.b,v.b))return !same_side(u.a,u.b,v)&&!same_side(v.a,v.b,u);return dot_online_in(u.a,v)||dot_online_in(u.b,v)||dot_online_in(v.a,u)||dot_online_in(v.b,u); }int intersect_in(point3 u1,point3 u2,point3 v1,point3 v2){if (!dots_onplane(u1,u2,v1,v2))return 0;if (!dots_inline(u1,u2,v1)||!dots_inline(u1,u2,v2))return !same_side(u1,u2,v1,v2)&&!same_side(v1,v2,u1,u2);returndot_online_in(u1,v1,v2)||dot_online_in(u2,v1,v2)||dot_online_in(v1,u1,u2)||dot_online_in(v2,u1,u 2);}//判两线段相交,不包括端点和部分重合int intersect_ex(line3 u,line3 v){return dots_onplane(u.a,u.b,v.a,v.b)&&opposite_side(u.a,u.b,v)&&opposite_side(v.a,v.b,u); }int intersect_ex(point3 u1,point3 u2,point3 v1,point3 v2){returndots_onplane(u1,u2,v1,v2)&&opposite_side(u1,u2,v1,v2)&&opposite_side(v1,v2,u1,u2);}//判线段与空间三角形相交,包括交于边界和(部分)包含int intersect_in(line3 l,plane3 s){return !same_side(l.a,l.b,s)&&!same_side(s.a,s.b,l.a,l.b,s.c)&& !same_side(s.b,s.c,l.a,l.b,s.a)&&!same_side(s.c,s.a,l.a,l.b,s.b);}int intersect_in(point3 l1,point3 l2,point3 s1,point3 s2,point3 s3){ return !same_side(l1,l2,s1,s2,s3)&&!same_side(s1,s2,l1,l2,s3)&& !same_side(s2,s3,l1,l2,s1)&&!same_side(s3,s1,l1,l2,s2);}//判线段与空间三角形相交,不包括交于边界和(部分)包含int intersect_ex(line3 l,plane3 s){return opposite_side(l.a,l.b,s)&&opposite_side(s.a,s.b,l.a,l.b,s.c)&& opposite_side(s.b,s.c,l.a,l.b,s.a)&&opposite_side(s.c,s.a,l.a,l.b,s.b); }int intersect_ex(point3 l1,point3 l2,point3 s1,point3 s2,point3 s3){ return opposite_side(l1,l2,s1,s2,s3)&&opposite_side(s1,s2,l1,l2,s3)&& opposite_side(s2,s3,l1,l2,s1)&&opposite_side(s3,s1,l1,l2,s2);}//计算两直线交点,注意事先判断直线是否共面和平行!//线段交点请另外判线段相交(同时还是要判断是否平行!)point3 intersection(line3 u,line3 v){point3 ret=u.a;double t=((u.a.x-v.a.x)*(v.a.y-v.b.y)-(u.a.y-v.a.y)*(v.a.x-v.b.x))/((u.a.x-u.b.x)*(v.a.y-v.b.y)-(u.a.y-u.b.y)*(v.a.x-v.b.x));ret.x+=(u.b.x-u.a.x)*t;ret.y+=(u.b.y-u.a.y)*t;ret.z+=(u.b.z-u.a.z)*t;return ret;}point3 intersection(point3 u1,point3 u2,point3 v1,point3 v2){point3 ret=u1;double t=((u1.x-v1.x)*(v1.y-v2.y)-(u1.y-v1.y)*(v1.x-v2.x))/((u1.x-u2.x)*(v1.y-v2.y)-(u1.y-u2.y)*(v1.x-v2.x));ret.x+=(u2.x-u1.x)*t;ret.y+=(u2.y-u1.y)*t;ret.z+=(u2.z-u1.z)*t;return ret;}//计算直线与平面交点,注意事先判断是否平行,并保证三点不共线!。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
相关文档
最新文档