- 在线时间
- 1029 小时
- 最后登录
- 2017-4-30
- 注册时间
- 2014-1-21
- 听众数
- 213
- 收听数
- 2
- 能力
- 100 分
- 体力
- 15807 点
- 威望
- 98 点
- 阅读权限
- 150
- 积分
- 8571
- 相册
- 0
- 日志
- 0
- 记录
- 3
- 帖子
- 1549
- 主题
- 715
- 精华
- 2
- 分享
- 0
- 好友
- 542
TA的每日心情 | 开心 2017-4-28 17:18 |
|---|
签到天数: 415 天 [LV.9]以坛为家II
 群组: 乐考无忧考研公益讲座 群组: 2017美赛两天强训 群组: 模友会交流视频 群组: 群组: 国赛讨论 |
1.数论算法 , y, {6 @1 D* ~/ }1 [# D% L
求两数的最大公约数 0 e8 T0 J' k9 `* i
function gcd(a,b:integer):integer;
. Q0 s/ u# a& x+ bbegin 6 a1 i% F @" Q5 l
if b=0 then gcd:=a 4 d& V4 M! `4 C0 s% o1 |
else gcd:=gcd (b,a mod b); ) G) e; w7 I. P9 V8 J
end ;
U# a# t& i4 P' `2 \# R/ d+ M' ~7 J( k5 X1 F
求两数的最小公倍数
8 R5 E2 K9 ~& v2 P$ h6 nfunction lcm(a,b:integer):integer; 8 e+ Q( f) M% f. ]& o
begin 7 |% S- Y, x4 Z9 j; `' o
if a< b then swap(a,b);
8 r, n3 U% Z- Z5 l# Q( Flcm:=a;
3 J2 f) v0 L, g# Lwhile lcm mod b >0 do inc(lcm,a); 1 o4 V7 n( ^# D3 E
end; 6 t7 {0 o/ ?0 ?5 I+ q
9 K$ r7 o! s4 y9 m
素数的求法 : j$ x" @! r) s
A.小范围内判断一个数是否为质数:
) e0 l2 b! t+ _5 afunction prime (n: integer): Boolean;
! ~( U# e) t, f+ \, @ Kvar I: integer; . m: h0 g- a& L: p4 j7 G% ]
begin
5 @3 W0 w, _- Y! ^ {/ ?for I:=2 to trunc(sqrt(n)) do & J) \. M4 m! M9 G) G
if n mod I=0 then
k* x' G5 c: w, Qbegin 4 j. {4 a$ @1 R2 L8 |
prime:=false; exit;
) V9 l1 _7 [3 `* C3 ?! S. `% w6 }, h/ ?end;
- g+ k9 x8 U5 h9 X5 k p$ Xprime:=true;
+ n1 a4 W) X0 G4 h2 B) T C Gend; : I* w* }2 ^+ K
# B, s; l- j7 Y$ _! F, sB.判断longint范围内的数是否为素数(包含求50000以内的素数表): & T C; e+ E, y! a
procedure getprime;
5 z0 e" f5 }1 W& k6 Ovar / k7 A9 G" ?1 H4 t6 H0 M
i,j:longint;
& l; J e! h. y, s3 W. A% Op:array[1..50000] of boolean;
- z( g+ u9 O- L. ^! A3 |begin ! ?7 P8 c) y4 [7 v7 A; [% r/ k
fillchar(p,sizeof(p),true); 2 f2 @: X6 M: E4 v0 l' U& A
p[1]:=false; ! J8 p5 `8 `$ E" O
i:=2; + k, Y9 R5 b2 d# f+ P
while i< 50000 do
6 y& v& I4 n8 K; {8 @6 j" gbegin
W' z& v. @0 k' ~0 |6 Pif p then
" Q4 q7 L8 g; j/ K6 [9 [/ t" Jbegin 2 Z; C+ y1 Y& ^) P$ @5 o2 {
j:=i*2; . |9 Q- b) F" Y6 G% F
while j< 50000 do
7 ` Q& r9 B4 W8 A f! D ubegin , B w, s5 z3 d, p0 f+ ]9 `8 P; _
p[j]:=false; ( S* a* o& ?# g/ F8 f
inc(j,i); " N8 M, U7 q# Z' x* U9 R; C0 |& K
end; # Q. B, ~6 r; T. U
end; 6 p9 ]; Q, V% C
inc(i);
# l2 M! A! d% C0 jend; 7 B0 W3 S/ u2 R; m, s% D
l:=0;
2 Q7 d, h, q& Yfor i:=1 to 50000 do
) t% m0 v) u# m2 q7 I0 Wif p then " g6 l' m. x* ]8 h2 L6 F
begin 0 b- e/ z" a; l0 b
inc(l);
/ G0 V$ s% q- upr[l]:=i;
3 D! M9 d1 o8 y: Q5 wend; : S! F. K+ R2 W; I) ?5 y
end;{getprime} ! w8 q8 b4 m1 j, E# K) @: Q. |# v0 K
function prime(x:longint):integer;
& r% j; D+ z: Gvar i:integer; $ `; n, {& K* p" @. [( c
begin ) c: K/ f4 u! }+ Z8 h
prime:=false;
$ W4 O) X! I% A' H4 c: ifor i:=1 to l do 6 W5 l( x: v$ Y$ M- f: U# C& I/ b% Y
if pr >=x then break
3 u4 V; ^: ?; h" ^& {else if x mod pr=0 then exit;
8 }) n9 i7 X$ ?' k( A: O/ @prime:=true; ! d0 K6 V; R5 a+ ]
end;{prime} 9 T# s7 i1 O7 Y
6 \- y+ `$ ^& d; {. k$ y; T" Y* P4 L2.
5 e) e$ c) T2 y) @" k" D; t% D0 O6 R+ A
3.
9 v4 |. e+ p3 I8 Q) T% _0 U% {! X
2 K X( t5 {* k8 ~4.求最小生成树 9 C4 I9 T! P) W& x3 u
A.Prim算法:
: G, T! o7 b* e5 s1 tprocedure prim(v0:integer);
' K2 \9 `- c* S2 ~( B9 W! Uvar
: i4 r( ^* O/ D5 d! elowcost,closest:array[1..maxn] of integer;
9 e( o m1 b( h* b, t9 `9 m2 [8 Ri,j,k,min:integer;
/ R- [& w5 x' Lbegin
+ T7 ^- X$ I, C, p' ~5 Kfor i:=1 to n do
7 R& [3 Z, P# d# T, ]! rbegin
& m6 @: K ^4 Y0 @% \lowcost:=cost[v0,i]; ( {$ I4 o i+ S1 c9 D8 x h
closest:=v0;
. ]8 B5 U2 X- ~end;
. S2 h6 n2 a! h$ l4 l; yfor i:=1 to n-1 do
+ I6 `) x ]" g9 m; g1 m- s! ^begin . ^( p* }# X$ a9 R8 s% F8 J
{寻找离生成树最近的未加入顶点k} . y7 P9 c7 Q" r0 A; W+ M3 H
min:=maxlongint; & v8 H$ S& @) N
for j:=1 to n do 7 o( s# h6 _, m
if (lowcost[j]< min) and (lowcost[j]< >0) then
( {' S: @' ?# _6 sbegin
. [% J7 U n8 m! p( }: t) Zmin:=lowcost[j];
% ]6 o0 P1 V) a& V# }k:=j;
1 l0 D" y# v$ N: T) _end;
& z$ g4 M1 Y6 o8 o; qlowcost[k]:=0; {将顶点k加入生成树} * U* r: @- i! L J: V* w
{生成树中增加一条新的边k到closest[k]} * \- o: j( i. v. r
{修正各点的lowcost和closest值}
8 U7 O! d9 K! d" ofor j:=1 to n do ! F. ^$ t& _ j6 ~. y; @& H+ ~
if cost[k,j]< lwocost[j] then ( O6 G+ [& p. @
begin
" O! c& p& z! \3 y) b( \) ^' }lowcost[j]:=cost[k,j]; $ W9 ?8 d9 |: L0 y
closest[j]:=k; 1 V; K. n+ t9 t7 T$ v
end; - k& \/ a/ W/ d4 V6 f- f
end; p! G8 B7 k/ [% V! {; m( O3 s
end;{prim}
2 E3 \0 ^, Z: X, @. cB.Kruskal算法:(贪心) 5 g; Z3 V) _, r$ E3 J" _
按权值递增顺序删去图中的边,若不形成回路则将此边加入最小生成树。
& ^( H7 P, F F# q4 j. vfunction find(v:integer):integer; {返回顶点v所在的集合}
7 H7 L( ^# x" c; Z2 Evar i:integer;
: _. w1 ^ v! @4 nbegin
) r, o6 {4 l5 b$ |i:=1; U" f/ P) ~8 p; S7 v
while (i< =n) and (not v in vset) do inc(i); # A& B2 ]1 W: O3 i$ T) r' f1 L% y
if i< =n then find:=i + r. ?; x+ L' S+ q' Q) h! ^8 v O
else find:=0;
; P Z7 E9 I m" zend; q; }$ [: u9 |
procedure kruskal;
9 V: H6 i# U. z2 G0 m( T* F. J; `: Lvar
3 U" F/ y5 P% w# @9 m O6 D) Ntot,i,j:integer;
8 l& M y+ V$ y u; x Obegin
8 L3 H5 x; T& q, Sfor i:=1 to n do vset:=;{初始化定义n个集合,第I个集合包含一个元素I} , @( a1 e* N5 z- _6 H
p:=n-1; q:=1; tot:=0; {p为尚待加入的边数,q为边集指针}
% z, y6 F# e$ Y+ J& Isort; ; V5 Y* h- J; [) Y- `" z3 P; I
{对所有边按权值递增排序,存于e[I]中,e[I].v1与e[I].v2为边I所连接的两个顶点的序号,e[I].len为第I条边的长度} % U! J. o% A' O0 \4 q; [& _
while p >0 do
1 W0 B4 B0 l. r/ B: ?9 {( xbegin 9 _2 f. [4 L# S; Z1 Z5 A
i:=find(e[q].v1);j:=find(e[q].v2); 6 n* T k4 {/ ~3 R z! D& v# O
if i< >j then
0 x/ r( z) H5 v) v" lbegin + g$ ?* u5 A q, l3 T5 I
inc(tot,e[q].len);
- L3 K' D6 b# O4 f0 B& bvset:=vset+vset[j];vset[j]:=[]; z" L* s# l3 g4 q: M0 ~0 Y+ k# e
dec(p);
* S z) H9 j$ q7 U$ t+ mend; 6 Z/ R U# } T8 \/ z$ K2 m
inc(q); ; E* V( L' _( ]( C& L
end; 7 V: R2 z- T3 |: @% e. d2 Q( Z
writeln(tot);
6 R! X7 i$ R8 e/ gend; ) H" s- A/ [. g" R: g7 T$ Y5 p
/ W$ R- e& q4 f' j h+ S; z/ M3 H5.最短路径
. n- j# ], c* PA.标号法求解单源点最短路径: , x2 O5 _- u) r
var
0 Y" N# r3 S7 @% F5 [! ka:array[1..maxn,1..maxn] of integer; ! Q+ ^9 o- X/ r; f6 [8 C3 }
b:array[1..maxn] of integer; {b指顶点i到源点的最短路径} # t; v3 r k8 I1 o; p9 ?& c
mark:array[1..maxn] of boolean;
- O, p' V: @* G$ S, Y$ T
4 L" k% }" j, g) }procedure bhf; $ O" N0 c; q5 N8 { g
var
% V9 C; ~ G% h4 ]& b6 Dbest,best_j:integer; # [* r, h" R+ n
begin 4 \. t d: z2 C+ {1 b
fillchar(mark,sizeof(mark),false);
, y; I( n; W, A/ M% t5 P0 q4 Smark[1]:=true; b[1]:=0;{1为源点}
2 | V' t0 H- }/ Q @repeat # x$ M2 ]+ S9 V; p: C9 t
best:=0;
- d+ f* o% D: w2 Y i3 \for i:=1 to n do - S* N8 {4 U' v$ F5 a8 \1 C
If mark then {对每一个已计算出最短路径的点}
9 C# i; g" M+ ]+ ?) F+ a5 [for j:=1 to n do & N, v' |* `2 l6 Z, M# z& V$ Y
if (not mark[j]) and (a[i,j] >0) then ; t% t' s$ B5 T2 I* U/ }' g
if (best=0) or (b+a[i,j]< best) then
6 r- a. q( f& [9 a& ]begin 0 y7 w; T( L7 l
best:=b+a[i,j]; best_j:=j;
; Z% [9 b4 F, h5 _end; / @( K3 V- G, z7 Y/ \
if best >0 then
" G; n& M4 c" z; [4 D, ^begin - ~) [3 _$ Y! {
b[best_j]:=best;mark[best_j]:=true; 6 S4 S' h/ a+ i- V- q# B% e
end;
2 {8 v2 J: m: E; muntil best=0; / s, j. }+ W. \9 V5 P# v b
end;{bhf}
+ Y2 m7 \# [+ `6 V7 m7 u g% V2 V, K; E) h5 z" `! \
B.Floyed算法求解所有顶点对之间的最短路径: & j6 y h: V8 [% E, |( l
procedure floyed;
5 S, Z" N; y( Z, Ibegin
3 ?9 @5 U! R0 ?8 L6 j C) G6 Xfor I:=1 to n do
, O+ F& S$ I( P1 s) bfor j:=1 to n do " M7 S2 F3 b. T( V
if a[I,j] >0 then p[I,j]:=I else p[I,j]:=0; * T# _* r' |& s
{p[I,j]表示I到j的最短路径上j的前驱结点}
, Y* O3 M: o( A4 H3 _for k:=1 to n do {枚举中间结点}
: C% A* [: E9 yfor i:=1 to n do % C0 I( Q! z& P5 g/ h
for j:=1 to n do
# H6 K! L g3 N) @if a[i,k]+a[j,k]< a[i,j] then
Q* }6 t. j0 }3 Q, K/ O* P/ s+ ibegin 5 s) _' o: X; ]" l {7 b) w4 j
a[i,j]:=a[i,k]+a[k,j];
5 u) f0 P) Z2 Z+ `- w1 c4 }p[I,j]:=p[k,j]; & x2 |2 ^1 n, z- G+ [& o: S" Z
end; * O8 X% _7 @" V' v
end; ) w1 H o9 z) c# r8 {, z- T
C. Dijkstra 算法: 7 w$ ]6 Z# [& z+ B
类似标号法,本质为贪心算法。 4 S& V9 d7 u8 I
var
8 w! H: T) r. G; Ra:array[1..maxn,1..maxn] of integer; 3 w0 v5 K. b' h4 W( V( e
b,pre:array[1..maxn] of integer; {pre指最短路径上I的前驱结点}
5 Y% V3 o" i( K" j7 omark:array[1..maxn] of boolean;
2 j1 ~! X/ e: aprocedure dijkstra(v0:integer); & x; h& q; Z$ F7 f6 J% S& J$ |
begin
) `! V: `( J" m! _! xfillchar(mark,sizeof(mark),false);
6 H" x! `1 e( v9 D% S7 Ffor i:=1 to n do $ a3 v4 l, `# l3 }7 f) E
begin 2 O6 ]' ]. q' ?- h0 I
d:=a[v0,i];
P9 Z5 ]% Z; l. I) g% Iif d< >0 then pre:=v0 else pre:=0;
$ T* b! P( ?( {4 X! s( _end;
7 d$ m+ T/ M0 n3 p: Smark[v0]:=true; % o8 o3 u, G4 b1 ?
repeat {每循环一次加入一个离1集合最近的结点并调整其他结点的参数}
j- {) ^ ^& t9 p! j8 p" m" nmin:=maxint; u:=0; {u记录离1集合最近的结点}
. b1 U0 y4 w, q& k6 X% j5 L+ efor i:=1 to n do 6 F, k. ]# ]6 N5 Y C' q3 i: d
if (not mark) and (d< min) then
( g$ l/ {7 j" z5 o4 ]: Ebegin
( F8 Q1 E t7 }4 C) u2 Xu:=i; min:=d;
4 x2 W9 H- D" }' @' cend; * W( P% K, [: P: m, H. c" T3 ^
if u< >0 then
0 r! R+ w. b5 i$ }# tbegin
# N3 l9 n- _7 V% z ~ S$ ^7 Q* Smark:=true;
# p' }' R( l6 Zfor i:=1 to n do ( I. o- P. c: y' s' b
if (not mark) and (a[u,i]+d< d) then
/ q l; a1 D$ sbegin & A- z( T4 w% ]4 B- e
d:=a[u,i]+d; 5 D+ A2 @- W" d. k
pre:=u;
/ U5 M; }1 G) }+ S/ Xend;
Q! y6 x: s+ @8 m; fend; $ }) [3 c# v7 ^& c( M: w1 R
until u=0; # B6 h4 g( v4 x# p; |) S
end; 8 \# Q+ H f# o9 \+ T% H
D.计算图的传递闭包
) g3 O l$ x5 O7 Q/ IProcedure Longlink;
, P% N% I$ f* @5 c& j1 KVar . `, W4 B) ]2 @6 S0 S
T:array[1..maxn,1..maxn] of boolean;
) Y$ J) m) x! C) i5 @- ZBegin
* U% a( Y; `/ c5 x# D3 i& FFillchar(t,sizeof(t),false);
- Q/ ^$ s: E- D3 o/ g% ? JFor k:=1 to n do
% n# @& `3 ?, C& c' o; }For I:=1 to n do 4 ?$ G- F% c6 {
For j:=1 to n do % x/ j( f3 Z3 n" _" i5 T
T[I,j]:=t[I,j] or (t[I,k] and t[k,j]); , b$ H$ P" T/ v& z
End;
' t4 O0 f1 y* @3 `3 A: m, \1 t4 |3 i
|
zan
|