- 在线时间
- 1029 小时
- 最后登录
- 2017-4-30
- 注册时间
- 2014-1-21
- 听众数
- 213
- 收听数
- 2
- 能力
- 100 分
- 体力
- 15803 点
- 威望
- 98 点
- 阅读权限
- 150
- 积分
- 8600
- 相册
- 0
- 日志
- 0
- 记录
- 3
- 帖子
- 1549
- 主题
- 715
- 精华
- 5
- 分享
- 0
- 好友
- 542
TA的每日心情 | 开心 2017-4-28 17:18 |
---|
签到天数: 415 天 [LV.9]以坛为家II
 群组: 乐考无忧考研公益讲座 群组: 2017美赛两天强训 群组: 模友会交流视频 群组: 群组: 国赛讨论 |
1.数论算法
) K# L. p. p5 N求两数的最大公约数
8 F' Y! q7 g4 d7 n/ }# @$ Ffunction gcd(a,b:integer):integer; 1 C9 B$ B9 H% K4 D6 J# k
begin 6 o$ p. e" }8 q" M
if b=0 then gcd:=a 7 c" y5 W3 l. s: U
else gcd:=gcd (b,a mod b); 0 B$ Y5 W& F* t8 r6 j* h! z
end ;
( m1 ?8 ?' u% t7 \1 j6 A/ o
* e- F. V8 I9 N X$ m求两数的最小公倍数 # M' x2 ` `, v+ e
function lcm(a,b:integer):integer; $ D3 j+ k1 u% i# ^, ^# @- T9 Y
begin }, B+ q: y" i3 l. m& c
if a< b then swap(a,b); * \7 H' \ m, ]* q( T2 O( V' l6 B
lcm:=a;
' L4 E" ~. Q1 _- ~/ O* }1 kwhile lcm mod b >0 do inc(lcm,a); & H4 C' Q1 n: P2 _* y* R0 ]
end;
B* E N5 i8 s5 B1 _) ~* l
! g6 a8 y4 M' d) V2 F素数的求法
, R) H4 F/ [" iA.小范围内判断一个数是否为质数: : j& [9 X$ I9 P# ^8 G# n/ i- P
function prime (n: integer): Boolean;
# F; ]( u3 e9 f* s4 zvar I: integer;
# S6 d5 {% o/ b. w3 ?begin ' o$ _( |6 r5 X8 {1 h3 B
for I:=2 to trunc(sqrt(n)) do
6 l+ m, H9 H4 bif n mod I=0 then ! `5 T# H8 r4 D% W6 v f3 N% `
begin ) |! s. G9 a- }/ E" k9 M0 d
prime:=false; exit;
% M6 j, g a+ X4 d/ a5 p Lend; % L& m4 L' ~( k/ T% c0 j
prime:=true; , m& {8 j2 F+ }
end; ) O! _0 ]0 v/ b) ?
( Q: p0 A9 w& i) B$ B8 L/ x1 A+ eB.判断longint范围内的数是否为素数(包含求50000以内的素数表):
$ [7 Y6 k* F4 W$ wprocedure getprime;
4 F7 K6 @6 @4 C: c- x8 h% l5 tvar 0 }: q2 `3 @ [ ~8 O0 r+ y( O
i,j:longint;
# Q. b! |& @, y% \p:array[1..50000] of boolean;
, w" Y n- ?" P. o7 |begin & f1 x0 I4 d4 W7 s+ r
fillchar(p,sizeof(p),true); k. }1 f+ ?9 T' L. U, f/ ]3 G3 z
p[1]:=false; 8 L1 y9 D- D; t9 t' u$ X5 L
i:=2; : Z0 V( W5 g( J0 @% b9 X: a
while i< 50000 do
+ m% T9 ~$ Z& {1 l% Tbegin * B" y2 E/ c' O/ R
if p then 8 Z0 x% q% ~' E3 x4 x/ _
begin
% G9 R0 Q! u2 Gj:=i*2;
7 x5 j3 h& \) p; T8 r. D# iwhile j< 50000 do & N% f, C/ I7 d j
begin ; I8 l) }" N, d/ p( J
p[j]:=false; ! _3 `) N" i* Y9 @) i( I
inc(j,i);
& J" _' a: ?/ D7 N7 Mend;
% k! e/ O% {0 Q/ p& I3 t1 \end;
+ Z; ~4 S, F3 l) \inc(i);
. P6 ~" V+ v. E# ~- xend;
( C6 L q+ \& ]3 {6 n! f' u% bl:=0;
& a H* z0 t! ]% V3 E" d% Afor i:=1 to 50000 do $ ?3 k8 c; H% q7 r$ p D
if p then 8 a! V: H# H- _
begin
( [( j2 C9 K% T0 c' B$ yinc(l);
8 X; O6 h( l P( o3 zpr[l]:=i; ! ]3 F! g3 o# e9 ~* h: C
end; / C, }8 c! y0 b
end;{getprime}
* T; E( ?9 e0 ]! o xfunction prime(x:longint):integer; # j$ s* k9 u& t: `% z
var i:integer;
) o. E- E) ^' o! X9 |+ jbegin # H$ F4 ]" v% i1 V) S
prime:=false; / g( T$ @5 n$ n1 R* q4 `
for i:=1 to l do
6 W j2 f8 w+ i6 ] c9 W; Zif pr >=x then break
" S" ]4 T2 ~5 b+ c4 P+ C7 D# Z# \else if x mod pr=0 then exit; 8 N/ e7 l5 H: `8 W* v0 L
prime:=true;
# z' Z. A3 d# H5 C* h$ [: p( K+ Zend;{prime} 5 Y2 x- j& }9 R. n' p0 f8 m5 i
( N. {. Y3 @5 }$ f2. $ d4 U U& r; T; _
% c/ g$ {0 g2 ?% }- @3 ]3.
5 g" I9 q! S7 D# L6 }3 ?% a0 k' `% x% _# n: T
4.求最小生成树 * ?& f5 R% Y/ C- S
A.Prim算法:
! m! g2 w2 Z4 [6 Xprocedure prim(v0:integer); 2 c) U2 R' j" B% c d$ H$ x
var
) q& K) S# @- [- i& mlowcost,closest:array[1..maxn] of integer; & ^# A8 N5 ~+ L8 W
i,j,k,min:integer;
. _* j9 P+ [# O7 G0 L, Qbegin
1 m: O+ {6 F+ g" I: z7 d6 g+ Jfor i:=1 to n do
% M* l( p5 F" u! C8 Z/ }4 A3 Dbegin
y) U& c( R4 H& Mlowcost:=cost[v0,i];
/ f6 T; V: Z1 Z) Y; Tclosest:=v0;
V. B; K4 z; k3 l" Qend;
5 z) V5 Y! \7 f# ^for i:=1 to n-1 do
) ?. e6 ^) |$ i% _& {* [begin O' J) f0 x5 j. I# V5 |
{寻找离生成树最近的未加入顶点k} * U. j( r t: [$ S/ e
min:=maxlongint; 5 j9 C: ?* `7 v! S, w, g0 Z
for j:=1 to n do
- t1 U; v. Q1 \7 w0 K/ h/ Dif (lowcost[j]< min) and (lowcost[j]< >0) then " I, x/ g" Q) ?& }7 {; A
begin ) T# v% f' @# B" c
min:=lowcost[j]; # O( O% r/ B! M4 E& e1 H% u
k:=j;
; _$ Q% ` [/ ^& y' _$ @end; 0 ?% z5 H, r7 I
lowcost[k]:=0; {将顶点k加入生成树}
3 {& v; K( p; \3 O{生成树中增加一条新的边k到closest[k]} , j0 h2 {0 B' H9 b) P
{修正各点的lowcost和closest值}
+ Q) n/ e- S# u% ]for j:=1 to n do ! `- { H' l( g# n/ r6 S P
if cost[k,j]< lwocost[j] then : R" P* o8 m) l) @ [
begin 8 c# H% o) X8 R2 a
lowcost[j]:=cost[k,j];
0 c. \ r2 L& c+ Iclosest[j]:=k;
# u) M- I% }* q s) d" _end; 7 J, s2 H' B* L1 ^: {7 x! q
end;
# j5 }% A# z, q0 r) @end;{prim} 8 M0 L8 g$ F( E. @7 q$ D
B.Kruskal算法:(贪心) 9 K* w1 T4 ~$ a; C ~0 g
按权值递增顺序删去图中的边,若不形成回路则将此边加入最小生成树。
) a& p0 [, l. O* @2 x" efunction find(v:integer):integer; {返回顶点v所在的集合}
$ B: C. E3 E3 ^6 E( z0 r" m5 }var i:integer; " _) W- S7 r# P" S# z
begin
" N7 h3 u) Z% D& b% mi:=1;
x1 [& K" ]' p' jwhile (i< =n) and (not v in vset) do inc(i);
6 W8 I( K" Q% x8 Y `' R, |if i< =n then find:=i " C& Y& e* a3 U4 g' P
else find:=0;
+ Y% l; Z8 Y' R0 j; Y3 ?end;
$ \: \' o' c1 u7 ?5 N/ u# Kprocedure kruskal; % T+ T/ W" p# ~
var
2 I: X: f( T& [9 E1 ?8 ^7 W/ y) |tot,i,j:integer; / _( L' f! U1 s2 f& T- t( ~; g
begin
! f0 R+ X" q$ `* C1 Jfor i:=1 to n do vset:=;{初始化定义n个集合,第I个集合包含一个元素I} " H- L8 {& w# b
p:=n-1; q:=1; tot:=0; {p为尚待加入的边数,q为边集指针} 3 I/ [( B4 _7 g$ J
sort;
/ Y) g, u i8 H% o% f1 J{对所有边按权值递增排序,存于e[I]中,e[I].v1与e[I].v2为边I所连接的两个顶点的序号,e[I].len为第I条边的长度} 9 g( |5 g- S' a
while p >0 do
. s( A/ s7 P: m0 L: Z+ z4 Jbegin 8 v2 C* w. d+ T& S/ z6 G
i:=find(e[q].v1);j:=find(e[q].v2);
4 H I0 x9 @' @ oif i< >j then 8 L. P- D6 L; A5 N' U+ G$ X
begin
" b* @3 ]& m$ I0 k) B, x: h- Binc(tot,e[q].len);
- | ^- ^6 [# H1 |! J( J1 l7 W8 m% Wvset:=vset+vset[j];vset[j]:=[];
2 p- x# t" k$ _ B) N* B* Hdec(p);
! L9 q4 X+ Y% J! K" A2 z' [end; 9 W! n8 f( F- P# M; F
inc(q);
4 I/ L6 {1 t* x1 W6 _end;
' I: x, }; g" H8 @writeln(tot); + d9 }, u# q. U; N2 i
end;
. ]) ?# _4 L( Y! O2 y. _& B8 o
/ ]& `* b$ a t A" f3 z+ K5.最短路径 8 I9 {! e, D J& u% `) g2 ~0 J! L
A.标号法求解单源点最短路径:
- n1 U; R+ g' w5 Z, p3 d8 v8 svar . B1 s# r) b8 n( y
a:array[1..maxn,1..maxn] of integer; V6 u; m; C2 T6 V7 @
b:array[1..maxn] of integer; {b指顶点i到源点的最短路径} * j+ X m* ^) Y+ d# \! g
mark:array[1..maxn] of boolean; # t7 I6 [+ z( w1 n2 Z
# ]& { a ~: C+ Fprocedure bhf;
8 [9 f! w: V! V* H2 {. h+ J8 svar
* i) r+ C! d g9 f) U3 \5 {* z ?best,best_j:integer; - U5 Q7 y" a* l& U, P4 |1 ]
begin
, k1 h. L6 G* m, V" @; Mfillchar(mark,sizeof(mark),false);
1 E, A3 q" V# Imark[1]:=true; b[1]:=0;{1为源点}
W$ { S( }* W/ K- Crepeat ) f+ j" i0 i5 I! \* J' h7 O# `* h
best:=0;
2 U/ ]8 ^5 z* H4 `9 zfor i:=1 to n do
$ I% e. d8 V- |2 MIf mark then {对每一个已计算出最短路径的点}
: k9 B1 E1 N/ @; l/ i, efor j:=1 to n do * T K1 y3 ?7 Q
if (not mark[j]) and (a[i,j] >0) then
+ O& `5 P; W8 O( @$ k' pif (best=0) or (b+a[i,j]< best) then
2 ^" a5 L# ]6 P6 i0 x9 Sbegin - l: Z1 E8 o9 c& W5 J
best:=b+a[i,j]; best_j:=j;
' v' W# ~; {9 Q6 `+ b" i# f" u7 Cend;
& b' c' f9 S4 D% aif best >0 then
' y$ R' L m7 gbegin 3 O$ O1 d( q7 `) ? y% E
b[best_j]:=best;mark[best_j]:=true; " V; L/ N' I) E7 Q' V/ t
end; 2 `3 M& y+ i* L: i# b
until best=0;
" ~% s+ n0 l$ @/ r' x5 Mend;{bhf}
& x/ W7 c" [6 k4 M' L, e2 H3 D
u2 s* D/ w t' t3 b3 `B.Floyed算法求解所有顶点对之间的最短路径:
) {% ^& [1 ?) S9 C* p$ I1 A5 Z- I+ ]: Hprocedure floyed;
* H6 v5 H8 e, Abegin
7 R8 C' l8 M' t% A- I, j9 q. [for I:=1 to n do
( Q1 c$ O6 S) {! T+ |7 cfor j:=1 to n do
& N0 T* H+ c# dif a[I,j] >0 then p[I,j]:=I else p[I,j]:=0;
9 r% @) q% d# ], u* V1 j{p[I,j]表示I到j的最短路径上j的前驱结点}
" `2 e% ?7 \& ~9 E6 j# @' Z: l( Y& gfor k:=1 to n do {枚举中间结点} : \+ m6 S3 a; X8 H9 b# _, m F4 ~8 e
for i:=1 to n do : D( H6 B. L- \ I! }
for j:=1 to n do
3 @# N& x. p+ a0 f2 _' x0 Lif a[i,k]+a[j,k]< a[i,j] then
0 |7 k7 i9 H* D' Cbegin 3 ^6 ?. n/ s0 y( p, I4 J, _) q
a[i,j]:=a[i,k]+a[k,j]; 5 x$ c9 P, Q9 ^
p[I,j]:=p[k,j];
6 R% {+ D- `: Y8 _4 Fend;
/ `: A; S- t) f. X7 Bend; " N0 @8 W: t- f. E) c; }
C. Dijkstra 算法: ) t% v1 Z% f D4 [" h3 Y
类似标号法,本质为贪心算法。 9 I9 l. R! w, C- L$ w: L
var
' c$ ^ O/ W4 A* Ra:array[1..maxn,1..maxn] of integer;
. K5 [* w8 ~7 A$ q2 |5 }' Q \b,pre:array[1..maxn] of integer; {pre指最短路径上I的前驱结点} - w* l, W. g8 C' n) w0 P) ]$ H7 v% L
mark:array[1..maxn] of boolean;
/ H. v( T; v! A9 H" Y# v5 r; n+ sprocedure dijkstra(v0:integer); 6 R1 ^, s0 D' v; z# y0 i3 q2 r
begin " y7 X6 R Y; h6 E; \
fillchar(mark,sizeof(mark),false); ; a5 X7 L- g) j" Y" X7 [# t
for i:=1 to n do ! c+ _3 i3 V c) D" u
begin
2 F3 S/ v/ n( Dd:=a[v0,i];
, ~4 d! h2 y2 Bif d< >0 then pre:=v0 else pre:=0; / e" _; K+ L5 o' m
end; 6 h$ f; J9 q) B5 |
mark[v0]:=true; . l" @, y( h9 `) N
repeat {每循环一次加入一个离1集合最近的结点并调整其他结点的参数} , S8 J) m, q% `: f) C7 b' l$ j
min:=maxint; u:=0; {u记录离1集合最近的结点}
f3 K! h- O5 P( D& Jfor i:=1 to n do
0 r6 d& I6 h; T5 u! ?# Sif (not mark) and (d< min) then % K8 Y( L$ b/ @/ }
begin
8 F$ m) T8 Z4 g- g: pu:=i; min:=d;
& f N w: L8 R8 Yend;
1 `! N2 o6 J7 t9 {$ A% \if u< >0 then 7 w* Q$ w+ h! e
begin
6 a4 _1 S, D& U8 i' x3 emark:=true; ' C2 W( \6 d) \/ x! e$ b0 {
for i:=1 to n do . v, f; a* `9 ^7 @2 c- W
if (not mark) and (a[u,i]+d< d) then
& e o w* } o9 U7 \, }- M, @begin
+ W/ f q1 \: xd:=a[u,i]+d; ( w5 I; h: Q, r
pre:=u; ' i! q. G% L: \, l0 T" i
end; 3 x0 Q3 U' `) [4 G, p
end;
' j; c3 B6 F" g1 E* ~5 w, Q; N% Tuntil u=0; ' _+ \' z3 S6 I! q1 T9 Y0 S, |7 Z
end;
1 Q* Z3 [1 u* b/ O% {) yD.计算图的传递闭包 / _$ Y- g5 Q; x w& ~0 L+ M
Procedure Longlink;
; M- }& P% I; {) ^3 O$ yVar
" l; K7 M" P/ N& M& p# ? ^# YT:array[1..maxn,1..maxn] of boolean; 6 u) k8 m; U3 t) E- h
Begin
g; z2 Q) [9 AFillchar(t,sizeof(t),false);
s) C6 q: M" i* iFor k:=1 to n do 8 l) {$ P6 T( W1 M( R
For I:=1 to n do
' V- B# |. O, l/ ]9 U' |* X) ~2 mFor j:=1 to n do ' y5 Q# O* K$ z+ G* I) w
T[I,j]:=t[I,j] or (t[I,k] and t[k,j]);
% V2 o/ f3 ? h* Y hEnd;9 g8 N/ B+ `- H8 C% z* z: H
+ q i9 Q% x9 w% P' D" S
|
zan
|