- 在线时间
- 1029 小时
- 最后登录
- 2017-4-30
- 注册时间
- 2014-1-21
- 听众数
- 213
- 收听数
- 2
- 能力
- 100 分
- 体力
- 15813 点
- 威望
- 98 点
- 阅读权限
- 150
- 积分
- 8573
- 相册
- 0
- 日志
- 0
- 记录
- 3
- 帖子
- 1549
- 主题
- 715
- 精华
- 2
- 分享
- 0
- 好友
- 542
TA的每日心情 | 开心 2017-4-28 17:18 |
|---|
签到天数: 415 天 [LV.9]以坛为家II
 群组: 乐考无忧考研公益讲座 群组: 2017美赛两天强训 群组: 模友会交流视频 群组: 群组: 国赛讨论 |
1.数论算法 7 b! V$ \, f$ u* z! p6 T
求两数的最大公约数 $ [& X& Q, G1 `+ z" g0 ]7 H
function gcd(a,b:integer):integer; ! u o; _! N" m7 s4 e! E& b7 v
begin
; Z2 L. ^- U) hif b=0 then gcd:=a
, w0 F7 P9 V% ~/ u. melse gcd:=gcd (b,a mod b); : V3 c' {! c- S0 U/ n
end ; ! g9 J. x( d& Z& o" N( m' a
. t; U4 |' R- t
求两数的最小公倍数
6 a; {8 c4 t6 L. f# L9 lfunction lcm(a,b:integer):integer;
: a9 [; O1 g8 \% ~4 a, t; J7 Qbegin
* e. t3 l* p3 ^2 M# E0 n/ a0 ^( hif a< b then swap(a,b); 5 Y/ u9 K+ ?5 C* W
lcm:=a; * n7 c5 E/ q: [7 n+ o
while lcm mod b >0 do inc(lcm,a); N) h5 k' i3 I
end;
b7 q# v4 ]) A$ S' U( E
h- m1 {! h2 q. L+ B. d' w# d( U素数的求法
! I1 K/ V' [ p* U) k1 ]A.小范围内判断一个数是否为质数: ( L4 ~0 ]0 ~8 \' h( K" C, x
function prime (n: integer): Boolean;
' [5 s% M+ U2 b/ }4 Y0 Rvar I: integer;
1 r3 c- N5 P/ Abegin 7 x1 j$ l" _ k0 Y8 x
for I:=2 to trunc(sqrt(n)) do : `( {' T5 k8 h( p+ ^
if n mod I=0 then
) K4 I1 [+ G3 x9 a& h) N Sbegin
# c, n4 e) N5 }& {$ k# Y- j$ bprime:=false; exit; 8 z! \ I D+ k: u$ N0 Z8 k1 Y4 T( T
end; ; a# R1 d9 Z2 F
prime:=true;
% I' A& J7 Q0 c, m Tend; & u6 a6 g: a" ` D; o0 U$ H6 |0 M
" ~& n" B6 v/ J; o
B.判断longint范围内的数是否为素数(包含求50000以内的素数表): 5 ?/ m$ s* r/ W
procedure getprime;
; w& P6 `4 y4 Ovar ! `; c1 z0 }+ y, H% D
i,j:longint; 6 Z! `6 P) u5 R- ^$ [
p:array[1..50000] of boolean; g. D- U7 A" o& O- }* w9 g
begin ' g& N* t/ D& Z! V% E8 f
fillchar(p,sizeof(p),true); 1 x/ m9 Q& `/ h
p[1]:=false;
" f( ^# C; z. o. U* F8 o0 oi:=2; + h9 n; N) Y: I
while i< 50000 do
3 |3 t- R( \. l6 W+ `9 ~. `$ w) ~: @( ?begin
$ ?0 g7 t$ V) | Q, R# eif p then 2 d9 V9 b E: K I6 |* y
begin
$ f5 L' K7 D/ uj:=i*2; : @0 b; A' R3 _% I& d: L
while j< 50000 do 6 I1 M( f$ N2 f% C
begin $ u0 V2 b; u8 z8 w8 {) k. D7 P9 i
p[j]:=false; ! B/ M. d4 W" [7 D
inc(j,i);
' _! }9 N; e. a; z4 V& e0 hend;
2 g' J" [; y0 [9 a7 Gend; ; D% s( K5 b O# C
inc(i); - n9 _. w$ x& x# f. ?3 j- f
end;
) p3 |( `5 { Q2 w) N% l" Cl:=0; ( i" d& W0 [2 f3 t x
for i:=1 to 50000 do / m) ]0 U( |+ C1 K( I1 b& y5 v
if p then : C8 ~! ^% r( ~
begin
9 A c7 f! ~, |! Z0 q5 ^7 Y! u5 e. D# Z5 Rinc(l);
- g, g# i; [/ _' `, Rpr[l]:=i;
# y# E) S% E* e- m9 Eend;
8 Y+ `7 g4 c. l# t! A/ Rend;{getprime} 2 G% y n* t. ~& { A
function prime(x:longint):integer; 5 z- k0 F+ F, t2 `
var i:integer;
. ^3 O! }9 j7 E' Mbegin
' s- O- X$ V9 j8 _6 J2 t4 Gprime:=false;
9 C; |# K l9 ^8 w* G; jfor i:=1 to l do
$ L5 ]; D m3 m5 s7 Aif pr >=x then break p9 X: R: _" N6 L
else if x mod pr=0 then exit; 5 z' L( r9 f2 k. d$ P o% K
prime:=true; 8 t: ^2 v8 Q6 |9 ~% b& x1 }* u+ b
end;{prime}
p- b8 r3 [4 K% T5 _0 w( i3 Y1 Y, L/ |, y
2. % {) ]! u, U# c% |0 q% }
, C8 B2 f, w' v3 C0 j3.
" f7 G: |. D( [& V7 E2 v
. l" ~6 ?( j* D( C4.求最小生成树
6 {+ a& {: l" X( H9 [" x, AA.Prim算法:
1 ~- j1 T* r7 O/ P* c! e2 ]" p, ]1 G7 mprocedure prim(v0:integer); ; |- F0 S% m0 d8 _! P, C; ~; \( y: Z
var 3 K2 ~* G8 k" ^' N1 r9 N
lowcost,closest:array[1..maxn] of integer; - _& F! X z$ e* \
i,j,k,min:integer;
: S. M& f# l& x, G% i9 z' ~begin
, |2 X, u9 ~4 k5 t. s" E0 Cfor i:=1 to n do
4 m8 F6 Y& U; o) ?6 l9 B Vbegin 8 R: u% D/ W3 N; m1 }1 e2 L
lowcost:=cost[v0,i];
7 `* M& ]$ `% y5 v; T5 X6 A% eclosest:=v0;
4 I' E* {- Q# j; r, f. r0 Oend; , Q9 @- ?. V* m# v. s! e
for i:=1 to n-1 do
9 z# @5 K0 J: H xbegin
- F; G5 t5 |' Z, G/ Q+ X" ^# _5 k# `{寻找离生成树最近的未加入顶点k} b1 d5 [6 i- W% ^3 f0 b. l6 I
min:=maxlongint;
# J6 L9 C6 H% l. M1 P$ b4 c, ~for j:=1 to n do & J+ N+ K7 C3 A8 J
if (lowcost[j]< min) and (lowcost[j]< >0) then
9 r" `% u* ^6 i, B2 gbegin
9 d; x5 d" W6 _' d6 xmin:=lowcost[j];
- v8 K4 r- u' C1 Z8 L( Wk:=j; + u- F3 `# I8 Q( T! T- w
end;
9 m# ?" S* o# ?$ g6 elowcost[k]:=0; {将顶点k加入生成树} / {& k: P5 t; D/ L
{生成树中增加一条新的边k到closest[k]}
9 f& G" l' ~; C L{修正各点的lowcost和closest值}
( [* e, A' v) gfor j:=1 to n do $ |- T. [) R5 {* I" W8 W
if cost[k,j]< lwocost[j] then ( n* Y9 d( ?% i+ N) E2 M0 x
begin
, s" ~& K3 H: U$ J3 N4 i9 S7 ^ Blowcost[j]:=cost[k,j]; $ C1 U: l5 p E& |6 [2 m
closest[j]:=k;
* n- Q! l3 s- n% j Kend; ! }1 o: I7 I' l. o$ i$ }
end;
7 y( w& P6 p1 n6 `* w) y0 m; Bend;{prim}
1 }6 h( Y, [! H' o# NB.Kruskal算法:(贪心) & x! H5 t2 Z$ c& w0 c8 n
按权值递增顺序删去图中的边,若不形成回路则将此边加入最小生成树。
7 ?. p9 H: U- {1 C/ wfunction find(v:integer):integer; {返回顶点v所在的集合} $ A7 }# V2 F& F; ~, V6 e9 I
var i:integer; % r' Z" w8 B# N1 [5 a
begin " T* Z& Q6 p- v4 U( ]/ V8 `) E
i:=1; ! p! R( u$ i& F* V2 P
while (i< =n) and (not v in vset) do inc(i); . }7 L& v$ l+ d0 N
if i< =n then find:=i 9 Q, o$ b4 u& M
else find:=0; - X" r8 J0 ?6 n4 y; u8 @
end;
7 J( V* g2 h* W1 p! L* a+ S$ tprocedure kruskal;
" s# j" o3 b0 w0 ]var
1 n7 N8 [9 `3 Btot,i,j:integer; 4 l3 u! Q/ C/ \. P
begin
0 k- h+ ?+ P1 Kfor i:=1 to n do vset:=;{初始化定义n个集合,第I个集合包含一个元素I}
2 J" M; _6 K ^p:=n-1; q:=1; tot:=0; {p为尚待加入的边数,q为边集指针} ' p# Y* }0 N5 e. U* H" v" T8 i
sort;
5 D% b3 W3 W' f& e( }{对所有边按权值递增排序,存于e[I]中,e[I].v1与e[I].v2为边I所连接的两个顶点的序号,e[I].len为第I条边的长度} o9 k' }: _; V K& h
while p >0 do 2 ^7 x) f+ e7 ~
begin 8 k: M$ F5 c" i) T1 W
i:=find(e[q].v1);j:=find(e[q].v2);
: s& {0 k: K1 \( Yif i< >j then , h6 o c; A# F3 a4 g
begin % X" ]+ m5 O+ [+ ~
inc(tot,e[q].len); ; ]9 M/ L8 C; n _* r
vset:=vset+vset[j];vset[j]:=[]; # n2 z7 ^6 R! P& ?( c$ g% z
dec(p);
) N* k9 j0 \# \$ s7 H6 g4 L7 Qend;
* Q5 i/ I. G, X% U; N! e- minc(q);
! I2 V8 `8 g. t: Fend;
( c# {1 N1 `, ]4 P% Qwriteln(tot);
: x- G3 ~1 B, x* S0 z; s) wend; 6 A6 e" Y$ S4 `3 o& ^
9 {9 F$ h) f: w: i9 p- J3 ]0 k5.最短路径
/ h7 i5 u9 H6 KA.标号法求解单源点最短路径: . [1 p* k5 c; ~! u
var ; D" \, c. y9 u0 |: E+ b/ ?
a:array[1..maxn,1..maxn] of integer;
( r- I0 Y: w1 L( J& Q5 Wb:array[1..maxn] of integer; {b指顶点i到源点的最短路径} : ^9 ], t: @5 S% U1 G- V3 ^
mark:array[1..maxn] of boolean;
2 ~, e1 X H& O5 x- G
% S+ A8 _+ u* Y7 Zprocedure bhf;
% }: @- p8 V/ Z0 g' M& F. yvar 9 d: i9 d: t& O! L2 U
best,best_j:integer; 0 H( K% r" G* q3 {
begin ; T% s- \+ M& F; D9 I/ Q
fillchar(mark,sizeof(mark),false);
' p0 G7 H# e( _8 a h. gmark[1]:=true; b[1]:=0;{1为源点} " x" U& @) _# [; ?
repeat
) s4 Z& d; v3 w# l/ W8 w- g" abest:=0; 3 U; q/ |9 C1 b+ j* e
for i:=1 to n do
7 n+ {9 k; _/ }5 E5 KIf mark then {对每一个已计算出最短路径的点}
# ^% b& L* f7 s2 h0 O+ X+ ofor j:=1 to n do
# Y6 C7 v8 w! fif (not mark[j]) and (a[i,j] >0) then ) ^! v- F2 R' X5 o; @
if (best=0) or (b+a[i,j]< best) then Q3 Q/ _9 i, L! q+ S- B
begin
3 I! k T0 ?9 f7 A. S; {; j9 ^best:=b+a[i,j]; best_j:=j;
: G3 ^1 l. [) t- w O$ R# ]# f# cend; $ b4 J- @# K9 V" \0 i/ t) a
if best >0 then
0 E- Z& ]0 D6 x$ v% h L+ mbegin 9 u/ j( L3 a1 b1 v5 k8 u
b[best_j]:=best;mark[best_j]:=true;
9 p* `5 s5 G* R! Q3 x# ^. dend; & v4 L' P' N, r4 ]) C0 P9 ]* w8 x) w
until best=0;
+ z: o( l' D9 V" a- W: f: Gend;{bhf}
0 D" z; s# ]6 X/ \" q3 A1 S7 w0 q( p2 H# G0 r7 [
B.Floyed算法求解所有顶点对之间的最短路径: 4 v* r5 l$ y5 w
procedure floyed;
3 c1 M7 e0 h& e, obegin / S1 r) O4 s- s T' {/ | a X
for I:=1 to n do 7 h. s3 T& `; w6 ?- f' J
for j:=1 to n do
0 q- M8 m/ u8 N/ ?( bif a[I,j] >0 then p[I,j]:=I else p[I,j]:=0; ' @1 E! w; N. z0 K' I
{p[I,j]表示I到j的最短路径上j的前驱结点}
% E) T. j7 ?- ?7 H6 Ufor k:=1 to n do {枚举中间结点} & ~5 ] `4 _4 L0 b' h3 P8 B( D4 v0 a
for i:=1 to n do 9 X m. i/ v5 o4 F9 G
for j:=1 to n do
1 e; S7 q6 A) d$ `9 c7 N8 u1 ~6 y0 I5 \if a[i,k]+a[j,k]< a[i,j] then
6 D8 }* u1 l/ R% g1 ]( U+ h _begin # O. m5 A7 [5 y% s. O+ a6 P% n
a[i,j]:=a[i,k]+a[k,j];
; c$ L" \+ s) G. O" e8 Yp[I,j]:=p[k,j];
$ |% `9 i+ D! S& l9 I Gend;
N7 W6 S* C* j& Cend; ' Z( n0 L4 G7 q& D+ x1 X9 @; p$ [
C. Dijkstra 算法: 9 ]+ N& }" c7 H! D% e
类似标号法,本质为贪心算法。 ; n, W. h" N. K, P5 X2 C, V
var
( Y* K7 O% D. I' w. x) Q5 ja:array[1..maxn,1..maxn] of integer; 3 p t( {. g8 {% T
b,pre:array[1..maxn] of integer; {pre指最短路径上I的前驱结点}
- Q) M' p% o5 W9 U* ]mark:array[1..maxn] of boolean;
/ {9 ]% J8 o* h. E# G B* iprocedure dijkstra(v0:integer); 8 Y2 @1 E/ g: F' i+ ]$ X
begin
7 j5 I9 w( |& xfillchar(mark,sizeof(mark),false);
6 m. i: s: U. z; _6 l. Q t' S% o* _for i:=1 to n do & \6 N6 G! S' s. S+ A3 a- u+ f
begin 6 ]2 R: Y, ?3 r0 f) b
d:=a[v0,i];
+ k" G6 M1 k1 J& c* Z7 v* f ?$ J4 Q) sif d< >0 then pre:=v0 else pre:=0;
* b! b( ]! t. xend; 7 Z5 U" C o, _, y1 h2 M
mark[v0]:=true; ( s+ Z: o" G# P2 U: w# [7 k
repeat {每循环一次加入一个离1集合最近的结点并调整其他结点的参数}
4 \1 C6 s _- n2 tmin:=maxint; u:=0; {u记录离1集合最近的结点}
3 q3 w7 y4 S- M$ q0 f6 Y' Ufor i:=1 to n do
8 l3 O( W% p9 O* A. y" Mif (not mark) and (d< min) then
; {* p% [# x! U* ?$ j6 T' wbegin
& U: z Y j0 j+ |u:=i; min:=d; 6 ` w [/ f7 e" U
end;
; ^, y( Z1 }# M8 mif u< >0 then & ?! Y: X) h' p% [" `# C6 X# v+ x
begin & v, D' J6 `: r H$ H; `, q& Q
mark:=true;
9 m0 z7 F, }. B g3 {' tfor i:=1 to n do
4 e v" [( g: N" q5 u1 Xif (not mark) and (a[u,i]+d< d) then
6 ~% J+ O/ ~; T4 ebegin
# G5 k" P# Z( h7 K% t. @- Td:=a[u,i]+d;
. p& p+ X2 Q: |8 I# Gpre:=u; 3 s% j5 ~3 D% o' n
end; % P0 @+ J, ^) A1 l8 R/ Y g
end; 3 x9 ~& |+ N" B. t* _8 {$ K
until u=0;
8 v. d# P& Y, v) i; [: w+ U( _' Iend;
; \1 T0 s* t; F8 t5 w2 q6 v) xD.计算图的传递闭包
1 r5 F ? u& G4 w: JProcedure Longlink; 0 k- ~- K) a% X( }$ U
Var 7 t4 N& Y( v5 l8 G" ^/ f" B" X8 v
T:array[1..maxn,1..maxn] of boolean; , O% h+ N/ j' P% T7 R
Begin
- d( O f6 f. `' o$ o8 qFillchar(t,sizeof(t),false);
& [& e3 H) p4 S8 M9 `For k:=1 to n do
0 D8 P4 Q, m& Q. tFor I:=1 to n do / K; E2 S6 N+ m' G" g; M* {# c
For j:=1 to n do 5 ]1 r5 [8 y+ Q" ~
T[I,j]:=t[I,j] or (t[I,k] and t[k,j]);
1 ]$ _# K3 G* }8 M0 G( ?, `# jEnd;
" `" k) _" w0 w- f2 g/ W1 X) F2 _) _6 f& j) O$ L$ E: D
|
zan
|