ACM小组内部预定函数
Ver 2.0 by IcyFenix
数学问题: |
|
|
|
2.精度计算——乘法(大数乘小数) | |||
|
|
|
|
字符串处理: |
|
|
|
| |||
|
|
|
|
计算几何: |
|
|
|
|
|
|
|
数论: |
|
|
|
| |||
|
|
|
|
图论: |
|
|
|
|
|
|
|
排序/查找: |
|
|
|
|
|
|
|
数据结构: |
|
|
|
|
|
|
一、数学问题
语法:int result=factorial(int n); | |
参数: | |
n: | n 的阶乘 |
返回值: | 阶乘结果的位数 |
注意: |
|
| 本程序直接输出n!的结果,需要返回结果请保留long a[] |
| 需要 math.h |
源程序: |
|
| int factorial(int n) a[0]=1; |
语法:mult(char c[],char t[],int m); | |
参数: | |
c[]: | 被乘数,用字符串表示,位数不限 |
t[]: | 结果,用字符串表示 |
m: | 乘数,限定10以内 |
返回值: | null |
注意: |
|
| 需要 string.h |
源程序: |
|
| void mult(char c[],char t[],int m) for (i=0;i<l;i++) for (i=0;i<l;i++) |
语法:mult(char a[],char b[],char s[]); | |
参数: | |
a[]: | 被乘数,用字符串表示,位数不限 |
b[]: | 乘数,用字符串表示,位数不限 |
t[]: | 结果,用字符串表示 |
返回值: | null |
注意: |
|
| 空间复杂度为 o(n^2) |
| 需要 string.h |
源程序: |
|
| void mult(char a[],char b[],char s[]) for (i=0;i<alen;i++) for (i=alen-1;i>=0;i--) for (i=blen-2;i>=0;i--) for (i=0;i<k;i++) result[i]+='0'; while(1) |
语法:add(char a[],char b[],char s[]); | |
参数: | |
a[]: | 被乘数,用字符串表示,位数不限 |
b[]: | 乘数,用字符串表示,位数不限 |
t[]: | 结果,用字符串表示 |
返回值: | null |
注意: |
|
| 空间复杂度为 o(n^2) |
| 需要 string.h |
源程序: |
|
| void add(char a[],char b[],char back[]) |
语法:sub(char s1[],char s2[],char t[]); | |
参数: | |
s1[]: | 被减数,用字符串表示,位数不限 |
s2[]: | 减数,用字符串表示,位数不限 |
t[]: | 结果,用字符串表示 |
返回值: | null |
注意: |
|
| 默认s1>=s2,程序未处理负数情况 |
| 需要 string.h |
源程序: |
|
| void sub(char s1[],char s2[],char t[]) |
语法:conversion(char s1[],char s2[],long d1,long d2); | |
参数: | |
s[]: | 原进制数字,用字符串表示 |
s2[]: | 转换结果,用字符串表示 |
d1: | 原进制数 |
d2: | 需要转换到的进制数 |
返回值: | null |
注意: |
|
| 高于9的位数用大写'A'~'Z'表示,2~16位进制通过验证 |
源程序: |
|
| void conversion(char s[],char s2[],long d1,long d2) |
语法:resulet=hcf(int a,int b)、result=lcd(int a,int b) | |
参数: | |
a: | int a,求最大公约数或最小公倍数 |
b: | int b,求最大公约数或最小公倍数 |
返回值: | 返回最大公约数(hcf)或最小公倍数(lcd) |
注意: |
|
| lcd 需要连同 hcf 使用 |
源程序: |
|
| int hcf(int a,int b) lcd(int u,int v,int h) |
语法:m_of_n(int m, int n1, int m1, int* a, int head) | |
参数: | |
m: | 组合数C的上参数 |
n1: | 组合数C的下参数 |
m1: | 组合数C的上参数,递归之用 |
*a: | 1~n的整数序列数组 |
head: | 头指针 |
返回值: | null |
注意: |
|
| *a需要自行产生 |
| 初始调用时,m=m1、head=0 |
| 调用例子:求C(m,n)序列:m_of_n(m,n,m,a,0); |
源程序: |
|
| void m_of_n(int m, int n1, int m1, int* a, int head) if(m1==n1) |
语法:kkfft(double pr[],double pi[],int n,int k,double fr[],double fi[],int l,int il); | |
参数: | |
pr[n]: | 输入的实部 |
pi[n]: | 数入的虚部 |
n,k: | 满足n=2^k |
fr[n]: | 输出的实部 |
fi[n]: | 输出的虚部 |
l: | 逻辑开关,0 FFT,1 ifFT |
il: | 逻辑开关,0 输出按实部/虚部;1 输出按模/幅角 |
返回值: | null |
注意: |
|
| 需要 math.h |
源程序: |
|
| void kkfft(pr,pi,n,k,fr,fi,l,il) |
语法:result=integral(double a,double b); | |
参数: | |
a: | 积分上限 |
b: | 积分下限 |
function f: | 积分函数 |
返回值: | f在(a,b)之间的积分值 |
注意: |
|
| function f(x)需要自行修改,程序中用的是sina(x)/x |
| 需要 math.h |
| 默认精度要求是1e-5 |
源程序: |
|
| double f(double x) |
语法:result=js(int s[][],int n) | |
参数: | |
s[][]: | 行列式存储数组 |
n: | 行列式维数,递归用 |
返回值: | 行列式值 |
注意: |
|
| 函数中常数N为行列式维度,需自行定义 |
源程序: |
|
| int js(s,n) |
语法:result=P(long n,long m); / result=long C(long n,long m); | |
参数: | |
m: | 排列组合的上系数 |
n: | 排列组合的下系数 |
返回值: | 排列组合数 |
注意: |
|
| 符合数学规则:m<=n |
源程序: |
|
| long P(long n,long m) long C(long n,long m) |
二、字符串处理
语法:replace(char str[],char key[],char swap[]); | |
参数: | |
str[]: | 在此源字符串进行替换操作 |
key[]: | 被替换的字符串,不能为空串 |
swap[]: | 替换的字符串,可以为空串,为空串表示在源字符中删除key[] |
返回值: | null |
注意: |
|
| 默认str[]长度小于1000,如否,重新设定设定tmp大小 |
| 需要 string.h |
源程序: |
|
| void replace(char str[],char key[],char swap[]) |
语法:result=strfind(char str[],char key[]); | |
参数: | |
str[]: | 在此源字符串进行查找操作 |
key[]: | 被查找的字符串,不能为空串 |
返回值: | 如果查找成功,返回key在str中第一次出现的位置,否则返回-1 |
注意: |
|
| 需要 string.h |
源程序: |
|
| int strfind(char str[],char key[]) |
语法:mid(char str[],int start,int len,char strback[]) | |
参数: | |
str[]: | 操作的目标字符串 |
start: | 从第start个字符串开始,截取长度为len的字符 |
len: | 从第start个字符串开始,截取长度为len的字符 |
strback[]: | 截取的到的字符 |
返回值: | 0:超出字符串长度,截取失败;1:截取成功 |
注意: |
|
| 需要 string.h |
源程序: |
|
| int mid(char str[],int start,int len,char strback[]) |
三、计算几何
语法:result=polygonarea(Point *polygon,int N); | |
参数: | |
*polygon: | 多变形顶点数组 |
N: | 多边形顶点数目 |
返回值: | 多边形面积 |
注意: |
|
| 支持任意多边形,凹、凸皆可 |
| 多边形顶点输入时按顺时针顺序排列 |
源程序: |
|
| typedef struct { double polygonarea(Point *polygon,int N) for (i=0;i<N;i++) { area /= 2; |
语法:result=area3(float x1,float y1,float x2,float y2,float x3,float y3); | |
参数: | |
x1~3: | 三角形3个顶点x坐标 |
y1~3: | 三角形3个顶点y坐标 |
返回值: | 三角形面积 |
注意: |
|
| 需要 math.h |
源程序: |
|
| float area3(float x1,float y1,float x2,float y2,float x3,float y3) |
语法:result=angle(double x1, double y1, double x2, double y2); | |
参数: | |
x/y1~2: | 两矢量的坐标 |
返回值: | 两的角度矢量 |
注意: |
|
| 返回角度为弧度制,并且以逆时针方向为正方向 |
| 需要 math.h |
源程序: |
|
| #define PI 3.1415926 |
语法:result=distance_2d(float x1,float x2,float y1,float y2); | |
参数: | |
x/y/z1~2: | 各点的x、y、z坐标 |
返回值: | 两点之间的距离 |
注意: |
|
| 需要 math.h |
源程序: |
|
| float distance_2d(float x1,float x2,float y1,float y2) |
语法:result=insidepolygon(Point *polygon,int N,Point p); | |
参数: | |
*polygon: | 多边形顶点数组 |
N: | 多边形顶点个数 |
p: | 被判断点 |
返回值: | 0:点在多边形内部;1:点在多边形外部 |
注意: |
|
| 若p点在多边形顶点或者边上,返回值不确定,需另行判断 |
| 需要 math.h |
源程序: |
|
| #define MIN(x,y) (x < y ? x : y) typedef struct { int insidepolygon(Point *polygon,int N,Point p) p1 = polygon[0]; if (counter % 2 == 0) |
语法:result=Pointonline(Point p1,Point p2,Point p); | |
参数: | |
p1、p2: | 线段的两个端点 |
p: | 被判断点 |
返回值: | 0:点在不在线段上;1:点在线段上 |
注意: |
|
| 若p线段端点上返回1 |
| 需要 math.h |
源程序: |
|
| #define MIN(x,y) (x < y ? x : y) typedef struct { int FC(double x1,double x2) |
语法:result=sectintersect(Point p1,Point p2,Point p3,Point p4); | |
参数: | |
p1~4: | 两条线段的四个端点 |
返回值: | 0:两线段不相交;1:两线段相交;2两线段首尾相接 |
注意: |
|
| p1!=p2;p3!=p4; |
源程序: |
|
| #define MIN(x,y) (x < y ? x : y) typedef struct { int lineintersect(Point p1,Point p2,Point p3,Point p4) //跨立试验 |
语法:result=lineintersect(Point p1,Point p2,Point p3,Point p4); | |
参数: | |
p1、p2: | 线段的两个端点 |
p3、p4: | 直线上的两个点 |
返回值: | 0:线段直线不相交;1:线段和直线相交 |
注意: |
|
| 如线段在直线上,返回 1 |
源程序: |
|
| typedef struct { int lineintersect(Point p1,Point p2,Point p3,Point p4) |
语法:result=mindistance(Point p1,Point p2,Point q); | |
参数: | |
p1、p2: | 线段的两个端点 |
q: | 判断点 |
返回值: | 点q到线段p1p2的距离 |
注意: |
|
| 需要 math.h |
源程序: |
|
| #define MIN(x,y) (x < y ? x : y) typedef struct { double mindistance(Point p1,Point p2,Point q) |
语法:result=mindistance(Point p1,Point p2,Point q); | |
参数: | |
p1~p4: | 直线上不相同的两点 |
*p: | 通过指针返回结果 |
返回值: | 1:两直线相交;2:两直线平行 |
注意: |
|
| 如需要判断两线段交点,检验k和对应k1(注释中)的值是否在0~1之间,用在0~1之间的那个求交点 |
源程序: |
|
| typedef struct { int linecorss(Point p1,Point p2,Point p3,Point p4,Point *p) //同一直线 if ((p4.x-p3.x)*(p1.y-p3.y)-(p4.y-p3.y)*(p1.x-p3.x)==0&& (p2.x-p1.x)*(p1.y-p3.y)-(p2.y-p1.y)*(p1.x-p3.x)==0) return 2; //平行,不同一直线 if ((p4.y-p3.y)*(p2.x-p1.x)-(p4.x-p3.x)*(p2.y-p1.y)==0) return 0;
k=((p4.x-p3.x)*(p1.y-p3.y)-(p4.y-p3.y)*(p1.x-p3.x))/((p4.y-p3.y)*(p2.x-p1.x)-(p4.x-p3.x)*(p2.y-p1.y)); //k1=((p2.x-p1.x)*(p1.y-p3.y)-(p2.y-p1.y)*(p1.x-p3.x))/((p4.y-p3.y)*(p2.x-p1.x)-(p4.x-p3.x)*(p2.y-p1.y)); (*p).x=p1.x+k*(p2.x-p1.x); (*p).y=p1.y+k*(p2.y-p1.y); return 1;//有交点} |
语法:result=convex(Point *p,int n); | |
参数: | |
*p: | 封闭曲线顶点数组 |
n: | 封闭曲线顶点个数 |
返回值: | 1:凸集;-1:凹集;0:曲线不符合要求无法计算 |
注意: |
|
| 默认曲线为简单曲线:无交叉、无圈 |
源程序: |
|
| typedef struct { int convex(Point *p,int n) if (n < 3) for (i=0;i<n;i++) { |
语法:Graham_scan(Point PointSet[],Point ch[],int n,int &len); | |
参数: | |
PointSet[]: | 输入的点集 |
ch[]: | 输出的凸包上的点集,按照逆时针方向排列 |
n: | PointSet中的点的数目 |
len: | 输出的凸包上的点的个数 |
返回值: | null |
源程序: |
|
| struct Point{ float multiply(Point p1,Point p2,Point p0) float distance(Point p1,Point p2) void Graham_scan(Point PointSet[],Point ch[],int n,int &len) |
四、数论
语法:result=BitLength(int x); | |
参数: | |
x: | 测长的x |
返回值: | x的二进制长度 |
源程序: |
|
| int BitLength(int x) |
语法:result=BitAt(int x, int i); | |
参数: | |
x: | 十进制 x |
i: | 要求二进制的第i位 |
返回值: | 返回x的二进制表示中从低到高的第i位 |
注意: |
|
| 最低位为第一位 |
源程序: |
|
| int BitAt(int x, int i) |
语法:result=Modular_Expoent(int a,int b,int n); | |
参数: | |
a、b、n: | a^b mod n 的对应参数 |
返回值: | a^b mod n 的值 |
注意: |
|
| 需要BitLength和BitAt |
源程序: |
|
| int Modular_Expoent(int a,int b,int n) |
语法:result=modular_equation(int a,int b,int n); | |
参数: | |
a、b、n: | ax=b (mod n) 的对应参数 |
返回值: | 方程的解 |
源程序: |
|
| int ext_euclid(int a,int b,int &x,int &y) //求gcd(a,b)=ax+by |
语法:result=Modular_Expoent(int a,int b,int n); | |
参数: | |
B[]、W[]: | a=B[] (mod W[]) 的对应参数 |
返回值: | a 的值 |
注意: |
|
| 其中W[],B[]已知,W[i]>0且W[i]与W[j]互质, 求a |
源程序: |
|
| int ext_euclid(int a,int b,int &x,int &y) //求gcd(a,b)=ax+by |
语法:result=prime(int a[],int n); | |
参数: | |
a[]: | 用于返回素数的数组 |
n: | 产生n以内的素数,按升序放入a[]中 |
返回值: | n以内素数的个数 |
注意: |
|
| 其中W[],B[]已知,W[i]>0且W[i]与W[j]互质, 求a |
源程序: |
|
| int prime(int a[],int n) |
语法:result=comp(int n); | |
参数: | |
n: | 判断n是否素数 |
返回值: | 素数返回1,否则返回0 |
源程序: |
|
| int comp(int n) |
五、图论
语法:prim(Graph G,int vcount,int father[]); | |
参数: | |
G: | 图,用邻接矩阵表示 |
vcount: | 表示图的顶点个数 |
father[]: | 用来记录每个节点的父节点 |
返回值: | null |
注意: |
|
| 常数max_vertexes为图最大节点数 |
| 常数infinity为无穷大 |
源程序: |
|
| #define infinity 1000000 |
语法:result=Dijkstra(Graph G,int n,int s,int t, int path[]); | |
参数: | |
G: | 图,用邻接矩阵表示 |
n: | 图的顶点个数 |
s: | 开始节点 |
t: | 目标节点 |
path[]: | 用于返回由开始节点到目标节点的路径 |
返回值: | 最短路径长度 |
注意: |
|
| 输入的图的权必须非负 |
| 顶点标号从0开始 |
| 用如下方法打印路径: |
源程序: |
|
| int Dijkstra(Graph G,int n,int s,int t, int path[]) |
语法:result=Bellman_ford(Graph G,int n,int s,int t,int path[],int success); | |
参数: | |
G: | 图,用邻接矩阵表示 |
n: | 图的顶点个数 |
s: | 开始节点 |
t: | 目标节点 |
path[]: | 用于返回由开始节点到目标节点的路径 |
success: | 函数是否执行成功 |
返回值: | 最短路径长度 |
注意: |
|
| 输入的图的权可以为负,如果存在一个从源点可达的权为负的回路则success=0 |
| 顶点标号从0开始 |
| 用如下方法打印路径: |
源程序: |
|
| int Bellman_ford(Graph G,int n,int s,int t,int path[],int success) |
语法:Floyd_Washall(Graph G,int n,Graph D,Graph P); | |
参数: | |
G: | 图,用邻接矩阵表示 |
n: | 图的顶点个数 |
D: | D[i,j]表示从i到j的最短距离 |
P: | P[i,j]表示从i到j的最短路径上j 的父节点 |
返回值: | null |
源程序: |
|
| void Floyd_Washall(Graph G,int n,Graph D,Graph P) |
六、排序/查找
语法:quicksort(int l,int r,int b[]); | |
参数: | |
l: | 排序上界,开始时l=0 |
r: | 排序下界,开始时r=数组元素个数 |
b[]: | 被排序的元素 |
返回值: | null |
注意: |
|
| 输出升序序列 |
源程序: |
|
| void quicksort(int l,int r,int b[]) |
语法:shellsort(int a[],int n); | |
参数: | |
n: | 数组元素个数 |
a[]: | 待排序数组 |
返回值: | null |
注意: |
|
| 输出升序序列 |
源程序: |
|
| void shellsort(int a[],int n) |
语法:sort(int t[],int n); | |
参数: | |
t[]: | 待排序数组 |
n: | 数组t[]元素的个数 |
返回值: | null |
注意: |
|
| 输出升序序列 |
| 小规模排序用 |
源程序: |
|
| void sort(int t[],int n) |
语法:result=search_bin(int *t,int k); | |
参数: | |
t[]: | 待查找数组 |
k: | 查找关键字 |
返回值: | 如果k在t[]中存在,输出i:t[i]=k,否则输出-1 |
注意: |
|
| 要求查找数组是有序升序序列 |
源程序: |
|
| int search_bin(int *t,int k) |
七、数据结构
源程序: |
|
| #define maxsize 100 int sqinit(sqqueue *p) //队列初始化 int enqueue(sqqueue *q, int e) //入队 int dequeue(sqqueue *q) //出队 int empty(sqqueue *q) //判空 int gethead(sqqueue *q) //取得头元素 void display(sqqueue *q) //显示所有元素 main(sqqueue *head) //函数使用样例 |
源程序: |
|
| #define m 100 init(stackstru *s) /*装入栈*/ int push(stackstru *s,int x) /*入栈操作*/ void display(stackstru *s) /*显示栈所有数据*/ int pop(stackstru *s) /*出栈操作并返回被删除的那个记录*/ main(stackstru *p) //函数使用演示 |
源程序: |
|
| # define null 0 main()
int length (struct LNode **p) ElemType get(struct LNode **p,int i) int locate(struct LNode **p,ElemType x) void insert(struct LNode **p,ElemType x,int i) int delete(struct LNode **p,int i) void display(struct LNode **p) |
源程序: |
|
| # define null 0 int pushlink(stackk *s,int x) int gettop(stackk *s) |
源程序: |
|
| typedef struct bitnode void createbitree(t,n) void countleaf(t,c) int treehigh(t) |