- 在线时间
- 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.数论算法
6 w3 H2 f9 `% R6 \1 \8 J+ D# }求两数的最大公约数 . G0 x8 J) B1 p4 ?) `; c, {9 {
function gcd(a,b:integer):integer; ( g* O2 l8 L( `/ Q: X; z. j
begin 5 }5 B/ K" |3 O# o1 g4 \+ K
if b=0 then gcd:=a ; n2 R* O5 z3 a4 G" ^
else gcd:=gcd (b,a mod b);
; ^4 X) Q; \- }, Y% J5 X( `+ j* vend ;
8 Y9 w; Z! F* g1 x; N
7 e2 @3 R1 ?( u) p. o) \% i: J求两数的最小公倍数 * {, L5 b9 K! X+ y8 A- ^
function lcm(a,b:integer):integer; 5 k* k5 c- m5 ]# J
begin
- y' }. F7 ^6 f' d2 D! ], [if a< b then swap(a,b); $ d7 H8 L5 o% ^) f! Q
lcm:=a; 5 A& Y) Y e- {9 Y) `4 v
while lcm mod b >0 do inc(lcm,a);
9 w1 M0 ?( P4 H9 B* Vend;
) x) }) r+ ^- D, Y+ U3 u* z S! w% B# n# k# M. K1 D, G3 c6 e
素数的求法 " J7 x5 C. \( A2 t. B9 q
A.小范围内判断一个数是否为质数:
- t* B6 h! i$ l. {( o0 X, [! \+ wfunction prime (n: integer): Boolean;
" b* G9 A2 C7 i8 J" nvar I: integer; ( `8 d# K, @3 G
begin
0 h/ \/ d9 N$ [* Z3 T1 Y0 Rfor I:=2 to trunc(sqrt(n)) do 4 s* H6 T+ _# k' T% K
if n mod I=0 then
( |# P7 q2 c% y1 Z3 u0 W% Ybegin
% z( k/ F+ ?2 ^# O" ~prime:=false; exit;
0 n' j! t7 M: p" c( U1 Gend; : Y8 y# `; {; \( w3 E# T
prime:=true;
2 p9 ` P# d( b# n; mend;
( p3 c/ f! v* } j! y" H8 C1 I! [8 M! B5 K1 P: f: ?5 k
B.判断longint范围内的数是否为素数(包含求50000以内的素数表): 5 B; L7 ~; H6 c3 C+ f ~; W
procedure getprime; $ T7 s9 N, w/ X. V* B$ R- y
var 1 d5 R( z3 `- f% M$ A
i,j:longint; , i% R- J& a) h, W O
p:array[1..50000] of boolean;
0 a/ e5 r- ]" D" Q5 V0 mbegin
; D8 O6 C) u2 M& Sfillchar(p,sizeof(p),true); ) X% f \5 c3 |/ h. J% U
p[1]:=false;
" f5 R, g* e( @' a$ |4 O- E% i9 ni:=2;
6 n7 a; R3 c2 P- iwhile i< 50000 do
M0 V4 s$ Q+ T9 L$ F6 h# D4 n, ~begin
0 y) e% n7 v9 J" L! Kif p then . m& U2 q& ^) k# w! C
begin * k( u% c1 Q& y% m& X
j:=i*2;
4 O3 g% C2 N8 Y* a) A& @) wwhile j< 50000 do
0 |) T/ y$ ~* nbegin
- I3 }- O! V3 J! H4 c* H4 ^1 @0 M' op[j]:=false;
9 o$ p. `6 P( V1 Pinc(j,i); . K+ ^1 S4 Q8 Z' e; p* B! G# e9 V
end;
2 U. v$ W( D) d0 J; tend;
1 q8 f( |* J* O3 E p. ^inc(i);
) z+ C# Q3 L4 d: M& Rend;
! m$ j- c; x. m* Wl:=0; 4 t' g8 |& C& |1 O% O, @. A$ F
for i:=1 to 50000 do
- Y) Y* q% p/ s2 {5 M. cif p then * G" S) ]: i. q2 x# P1 y* @
begin
. y; |( Z- _* a. ~# _) ]inc(l);7 a& v& Q9 \6 k
pr[l]:=i;
" `+ [6 F! M* D5 |5 aend;
' |3 _& \! X# d2 @9 Qend;{getprime}
1 ^: p2 }- L. T4 H1 J9 s; U, Hfunction prime(x:longint):integer; 7 j% j' W( [3 H# T' a! k$ Z5 q
var i:integer; : X4 w7 N. R0 U# |9 D I* T1 ~
begin 1 i7 r/ k1 `8 U7 {, {& C: r) U2 M
prime:=false;
, b. L; L; C% i I1 u) Efor i:=1 to l do 4 I; t# n+ X- M; F- ]7 q: Z
if pr >=x then break - E$ E; s% ^/ m* ]! z0 M1 j& [; K9 V
else if x mod pr=0 then exit;
* A. u$ M" ]6 |prime:=true; 7 v! A. s, d% X z
end;{prime} * k9 t! {+ Z/ v8 e: C$ g9 [
3 Y1 Z u" ~% F2 }; u5 I7 W2. 8 d% _8 P3 j1 J- |8 i8 z$ K
; u, D2 u B4 ~' Z! ~3.
4 s. F# M- J+ d7 r6 Z! t, F; Z' |0 p. p
4.求最小生成树 4 g! Y, u4 Q* N6 ?9 d( `
A.Prim算法:
7 q# `/ A( A8 x) E: p Nprocedure prim(v0:integer);
2 t/ q9 o/ l4 w P6 \5 R1 A4 ` gvar
! v; N: W0 \- S. l# `lowcost,closest:array[1..maxn] of integer;
1 Q& t2 B3 W$ j" o2 w8 li,j,k,min:integer; + Y$ Z7 Z& s6 G5 {
begin 8 ?# i! L9 J8 W. z) L- m; t$ I3 q
for i:=1 to n do % Y, F- e' q* U: B8 D# U
begin % `9 `% f3 V0 Y0 I- ]! x
lowcost:=cost[v0,i];
$ p" {& `7 q/ x% d- i9 lclosest:=v0; # W* ~+ t3 u7 O
end;
8 I+ S7 g4 m2 K: u0 y# Yfor i:=1 to n-1 do
4 Z5 d5 m- f/ R* H& xbegin
9 W+ g* I+ r3 x9 a/ ~ Y{寻找离生成树最近的未加入顶点k}
2 W/ A' k/ j4 imin:=maxlongint; 8 @+ R6 i7 u$ u X9 y. o6 [) i) m% G
for j:=1 to n do ' Z0 x' t# z& }- k/ Y5 B
if (lowcost[j]< min) and (lowcost[j]< >0) then * O" a- W2 X, l2 g0 _9 m6 w
begin 7 [2 p: ~3 R( V- E& t# i
min:=lowcost[j];
- n# @5 o: D& n6 a' A) {, |. _9 jk:=j; + G: G; L2 w9 G" z) F" p
end;
- A2 X4 {: Q- c/ ]7 `lowcost[k]:=0; {将顶点k加入生成树} $ L5 P, N& B V% w9 b" _0 _
{生成树中增加一条新的边k到closest[k]}
3 X3 Q6 M$ }; \. o/ y{修正各点的lowcost和closest值} 4 ]& v% z7 h( ^, O$ p, j" D
for j:=1 to n do # I0 J8 @8 n F/ X
if cost[k,j]< lwocost[j] then , F) Q7 u" W- s3 e& _
begin
5 d! Q {5 H+ l" y0 ^2 ~) [6 hlowcost[j]:=cost[k,j]; * d7 g, r h7 ^" Y
closest[j]:=k;
8 s: \: U: U7 l( {# i' k7 l" @end;
$ b9 E/ z6 p! d* Kend;
* [9 l- G( E/ p: z/ [$ V) w! }) y" xend;{prim}
5 \6 ~2 H: w2 u" l5 @B.Kruskal算法:(贪心)
8 m" ]/ V/ ]1 F按权值递增顺序删去图中的边,若不形成回路则将此边加入最小生成树。
2 j9 ^- P' ^. j e6 R* Xfunction find(v:integer):integer; {返回顶点v所在的集合} : \- C |( z, j' a; c: ]
var i:integer; # G' X% {7 A4 ^
begin + M1 ?8 d) o- z+ p
i:=1; 4 [( G" |* }! o1 U( n
while (i< =n) and (not v in vset) do inc(i); 1 t# A& E' ~3 O1 S! w0 Y9 G/ p( V( U
if i< =n then find:=i $ G4 ^% m& [" K9 \& K
else find:=0; 1 { g3 v( X9 {& n+ P% z
end; : n9 w% L2 H& L
procedure kruskal;
' b$ J- g; X+ [; I. n2 F# Z$ N" Ovar
+ j% ?; f! \, h0 stot,i,j:integer;
( c5 c2 y& W# R C2 ubegin
' f- u, v9 s! wfor i:=1 to n do vset:=;{初始化定义n个集合,第I个集合包含一个元素I} ! [. {4 ]1 M0 s3 q
p:=n-1; q:=1; tot:=0; {p为尚待加入的边数,q为边集指针} 8 u* |; U1 g* r+ m$ @8 P0 _9 f( h
sort;
2 T" b* i, V: h3 [; \- R{对所有边按权值递增排序,存于e[I]中,e[I].v1与e[I].v2为边I所连接的两个顶点的序号,e[I].len为第I条边的长度} % k) h; E! W, s2 r6 |0 _: r% K
while p >0 do ; X, c6 [; w$ ?5 F/ E, L- \
begin , X/ x1 @! f+ B
i:=find(e[q].v1);j:=find(e[q].v2); ; S2 k7 \3 c8 A8 e
if i< >j then
2 z* K" {9 i. W5 M/ x7 u" vbegin 8 C w& @6 l& f+ M+ P; V9 O" u
inc(tot,e[q].len); 6 }: z& }: z) @0 K7 J# B
vset:=vset+vset[j];vset[j]:=[];
3 U4 q- S7 e5 s' J! Edec(p); # s5 `' \: {; i0 q: T2 m. X. K1 y
end;
9 _! u- u# B tinc(q); 5 u J$ k9 A8 t+ T$ N2 [# u m
end;
( S ~/ N1 }1 }6 N" C! A& ^writeln(tot); & T& B, [0 P& F# e
end; * w# t* |5 Y/ z o) M
7 P5 w& @ P1 c8 S% p5.最短路径
- P2 W- z% K; l) Q& pA.标号法求解单源点最短路径: 9 l6 l# }, _) U9 M
var ' `2 J; _. G' u b9 o% _
a:array[1..maxn,1..maxn] of integer;
$ i4 p6 P# Y+ ^ t$ Gb:array[1..maxn] of integer; {b指顶点i到源点的最短路径} 6 s5 T' C! w# ~0 S. M! I
mark:array[1..maxn] of boolean;
, {. m$ V7 E7 |0 r( a0 V: N' z" j3 S6 M8 A+ r3 T
procedure bhf;
4 l0 v, w8 a4 j5 L5 r3 Pvar 9 L2 ]. v( U( f- A/ j
best,best_j:integer; 3 |# P" B( Z* A) Q" b
begin 8 d5 p. b: n( ^* ]
fillchar(mark,sizeof(mark),false); # o9 o: v( w- D. R9 A8 p* f
mark[1]:=true; b[1]:=0;{1为源点}
* B% Q3 a1 h% A9 nrepeat ; R4 h% a5 I6 F/ A1 M
best:=0;
; b3 I% b* E5 s& R! |for i:=1 to n do 7 |4 q$ J e' p& c# v) i
If mark then {对每一个已计算出最短路径的点}
0 r6 M$ `0 N9 N" d+ p |for j:=1 to n do
$ I4 p* Q' J7 {2 n2 @% x b% Pif (not mark[j]) and (a[i,j] >0) then
( ^; m) i) l" z" V4 `$ wif (best=0) or (b+a[i,j]< best) then
, Q0 Y$ x- A q& F1 \begin
! b r w6 F2 sbest:=b+a[i,j]; best_j:=j;
' V% X7 p- t3 {0 Nend; - U) L' {5 e) S$ k/ R9 x
if best >0 then
" R. P4 L3 g N5 J, `0 v/ y7 |& @0 fbegin
3 {) l a; X# q: { qb[best_j]:=best;mark[best_j]:=true; 3 d% U% V3 W* {& n
end; 0 {6 f. F; w7 t1 @& V$ i
until best=0; + R2 n7 E& e5 B- {0 ]
end;{bhf}
' H, e. S! I) X$ f3 C# Y( ]7 H- p) z+ V* ^. U) S; D/ D
B.Floyed算法求解所有顶点对之间的最短路径:
4 T( v3 r0 S" u. }* H& G& H. s9 iprocedure floyed;
$ _; G# ~4 g/ R. h" T. |# G" Ebegin & V. v% z' ]2 T) j
for I:=1 to n do
q/ P4 j. d! W* N7 O4 O H6 ^; ifor j:=1 to n do 1 o: s8 @' s* t2 O. e& v q; ^
if a[I,j] >0 then p[I,j]:=I else p[I,j]:=0; ; r$ }6 g A/ G% \1 |4 q
{p[I,j]表示I到j的最短路径上j的前驱结点}
; u5 m; U) q; o& W dfor k:=1 to n do {枚举中间结点} ) F* [5 S) G8 \; Z( Z
for i:=1 to n do - s( q% L( d8 f
for j:=1 to n do
6 a" b/ X' G, W4 K" i; G8 F8 x3 pif a[i,k]+a[j,k]< a[i,j] then q+ _/ d( d) V0 b0 U! t( |/ U
begin ) I n# ]0 E. V9 k+ x; \0 Q: @
a[i,j]:=a[i,k]+a[k,j];
; D* y( B4 G6 t+ L- w. xp[I,j]:=p[k,j]; * Y0 ^2 o7 k6 q$ o* A7 b: p; o9 {
end; - N, O) y5 ? M5 U# e0 B4 n
end;
# N" @2 i1 V0 F+ ~' HC. Dijkstra 算法:
& o9 f' X# ?: F, p( ^) n类似标号法,本质为贪心算法。 3 R g4 w0 R% F# e/ [2 K
var
# m3 q3 G+ \3 m: E) ~9 ?- ha:array[1..maxn,1..maxn] of integer; 8 M+ W# @$ c# b
b,pre:array[1..maxn] of integer; {pre指最短路径上I的前驱结点} - A$ c' Q: C5 n2 Q0 d# V2 W- o. ~
mark:array[1..maxn] of boolean; 2 [, h0 k- o+ O+ Q9 Z) s' i
procedure dijkstra(v0:integer);
% v6 D9 b/ [$ [. O! ^- F5 Fbegin
5 j7 X3 w+ r& f" _, {0 I. E$ ofillchar(mark,sizeof(mark),false); / G9 {; g. M& e2 m: U' ~8 l7 M
for i:=1 to n do 7 U6 @7 u( V+ s( o9 i8 @; ?
begin $ x5 g: C& Q8 S4 ~1 o, T5 k
d:=a[v0,i]; . A; c Y3 `7 [$ b) B
if d< >0 then pre:=v0 else pre:=0;
' k1 ]" ^% D+ X8 f/ g7 zend; ; | Z2 O* a5 u; v2 \$ w/ R/ F
mark[v0]:=true;
! J. i, g$ b6 g& g% A' Lrepeat {每循环一次加入一个离1集合最近的结点并调整其他结点的参数}
( e& Y N/ N/ M. X vmin:=maxint; u:=0; {u记录离1集合最近的结点}
. Q. H; n% Y9 ]- _& Pfor i:=1 to n do ' s: Q$ r: q9 y& C# _
if (not mark) and (d< min) then
0 K0 Q# a- E; Ebegin 7 H6 `! P% \ x/ g) M
u:=i; min:=d; ! j- ^$ C/ O$ C& {; ?
end;
: M+ |5 I+ b# iif u< >0 then
0 U3 ~( E/ ~' f8 S/ dbegin
# @3 k8 w; C* F, E* X6 nmark:=true; T2 g6 `5 `- j& B1 m r. W b6 J
for i:=1 to n do ; `! y% `7 p& D3 y, f$ e1 j
if (not mark) and (a[u,i]+d< d) then
: t1 X' {7 R/ ybegin
4 @% {! J7 O- h/ fd:=a[u,i]+d;
$ g8 ~2 ~1 \- b! R( ] p- }pre:=u; 4 h; B6 l. v( W
end; ' a- n$ l q, ~ C* X# X- y
end;
$ z$ Q& N. |8 i) k5 U6 Cuntil u=0; : b% Z+ ~, K2 d
end; / y5 m" Q& T7 M" Q0 d
D.计算图的传递闭包 3 m% h, g! C; H# P
Procedure Longlink; ' o j: ]9 {7 B$ e9 q O$ E _6 ^! S
Var " Q8 e1 Q( v+ x5 r: l4 U. e
T:array[1..maxn,1..maxn] of boolean; / W1 s; d# m2 _1 Z- L) s' l
Begin ; [, R0 j* r E7 Y. N
Fillchar(t,sizeof(t),false);
6 E" U3 M' Y$ v0 kFor k:=1 to n do 8 g: r4 @8 m0 c% _
For I:=1 to n do f- K- f* ^, N3 v+ v4 V
For j:=1 to n do - E9 v+ h2 _/ e0 @" W7 m3 E
T[I,j]:=t[I,j] or (t[I,k] and t[k,j]);
, s# {2 z) e O* BEnd;0 N: I, ^) V" o7 u5 M `2 r
8 w: m9 t1 d4 i5 A& H3 n8 y& B
|
zan
|