- 在线时间
- 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.数论算法 9 `& B5 L6 X, ^$ k& M( ]
求两数的最大公约数 : U5 a/ X" y% a6 | P- C4 j
function gcd(a,b:integer):integer; 8 O4 a, U; k5 i: h& P
begin
4 N) c5 f0 J$ O) uif b=0 then gcd:=a . t& L% ]8 a- Q
else gcd:=gcd (b,a mod b);
8 H" P C+ k, ?# J. b( Eend ;
- |& P$ l; M. b' x5 S0 T$ a
9 p. m/ {6 r" @1 D, |8 P+ S8 g, Q求两数的最小公倍数
- B/ }/ P# |) r F. [$ d" F, l. k2 v4 L# lfunction lcm(a,b:integer):integer;
5 X" x+ L6 ~* ^ l( w. E) `begin + q, m/ Z" N# u7 m
if a< b then swap(a,b); & H5 v) m0 M0 v8 u# W
lcm:=a; $ y3 }# m. G6 E) I
while lcm mod b >0 do inc(lcm,a); ' ?4 h$ N$ @! W3 r% G3 d; |
end; - C# y' k1 U A+ O. |
6 t2 @8 w+ k4 [0 n素数的求法 ) [# n$ v& ?; l# h- h- f* J
A.小范围内判断一个数是否为质数: ) l( l; x2 T; ?( Y. |* s
function prime (n: integer): Boolean;
, t5 {( f X. J/ d% c! }var I: integer;
) w ^4 J. i9 D, _begin
$ a( S X5 ]; y( R5 W8 M/ ~for I:=2 to trunc(sqrt(n)) do / g1 }" P0 \0 V6 S
if n mod I=0 then
% o9 u+ T* l" p. O8 j/ }begin
( v! \- v2 [1 q# A8 b: Oprime:=false; exit;
( O: o8 t* l. o, W8 `6 Aend;
_1 U+ z$ m) @2 Wprime:=true; / E8 v; ?/ v- h7 H9 y
end;
0 p8 z" e) ^- t/ B: k/ c
3 q* R4 T& t! BB.判断longint范围内的数是否为素数(包含求50000以内的素数表):
9 h8 Y# J, k; C2 aprocedure getprime; 8 b5 ~) T, O; w& G/ m$ A( d! L" k1 H
var I% H j; L4 F, Q, g
i,j:longint; : B$ f. |/ a/ k8 O
p:array[1..50000] of boolean;
! o6 }8 Z Z* v2 t' nbegin ; u& ^- _1 f n" B
fillchar(p,sizeof(p),true); % d+ K$ g0 O! n" y# M
p[1]:=false; c3 s F3 {/ S! e0 N: H% m
i:=2;
6 l( l0 E( k, n- @9 lwhile i< 50000 do ; c- w3 E( m- _" V' w* I
begin 2 L2 d+ _' o2 x) S
if p then 2 y4 c% k6 S& m7 ^
begin
2 [$ @' O: N W: p& tj:=i*2;
9 M9 S9 [/ G( Bwhile j< 50000 do
. Z: p0 M6 N8 Hbegin
( N; O3 i0 z/ Tp[j]:=false;
0 z- G/ _ i/ y" a, `inc(j,i); 4 b/ j" z, O! C( [/ M l
end; 2 y0 v1 d9 O+ O; q& k: e
end; ' C7 A3 ]4 I" p
inc(i); + k+ Z; L T5 r- q; t- w
end; 8 s& d4 a* v1 i6 y) v* @
l:=0;
, t2 ^* u: ^+ `8 U8 \7 o; Vfor i:=1 to 50000 do # m& N' ~5 w) i1 w1 P* S8 M& [
if p then " ?' f4 ~+ I" d
begin
- ^9 \4 z! x% f; ?7 ?inc(l);
8 b7 ^5 x) ?- u# k" ~5 Hpr[l]:=i;
! i+ e, }+ y$ d! M V; Oend;
7 [. I" ^" L3 |- x0 `end;{getprime} 2 j1 \4 {# w- @9 j4 K. d4 U" L
function prime(x:longint):integer;
0 y2 M3 ]8 b- _8 k1 z' M6 pvar i:integer;
) `, l/ _& v6 ^' A: Qbegin * ^. f5 G1 P9 Q" j* t$ U
prime:=false; * C; f; K" T/ [/ l- V/ A$ |# Z) f- ~
for i:=1 to l do
/ r7 o' }) Y- w- P0 n4 C: fif pr >=x then break
6 p- c0 }" K; h* A3 jelse if x mod pr=0 then exit;
! V$ s: I O6 {' c3 X) E. tprime:=true;
+ `& c2 P' Y, g0 E& Mend;{prime} 5 s: h# `! g5 C, f
5 J4 E' H9 F2 t. W6 P4 F( E7 X2.
: t9 o8 t z- E2 H: p g0 k' b9 c
) k: v7 K$ f$ P; \/ r ` K6 ` t f3. & H% z, {2 z( h, r/ `3 _
. V2 Y+ Z* U+ g3 u3 {. Z v4.求最小生成树
! L6 u. l6 ~& y- W6 V" U. G8 fA.Prim算法:
6 V0 a0 H* b! N) j8 G7 pprocedure prim(v0:integer);
) k) s" \4 U9 Y7 q9 o$ S* {var
* p6 H( R6 g5 jlowcost,closest:array[1..maxn] of integer; 9 a7 G7 ^8 L( f9 @: r
i,j,k,min:integer; ; O/ e6 I- R! \* k4 \/ S5 A
begin . ]- D' y7 p% N9 b" f
for i:=1 to n do & m7 T+ K* r; V- f0 ^6 k4 K: o. T- }
begin
& X- N6 B; j9 J) }' r9 jlowcost:=cost[v0,i];
: H4 S$ b9 n9 u& H0 i! wclosest:=v0; 6 T) S9 n: r1 B1 v. k }, P: x+ N
end; + M5 x" O# O0 t- v ~2 d" w* X$ v
for i:=1 to n-1 do
/ b. Y2 c' Y# a- {/ Kbegin
: D& M* W" X; ~5 T4 f{寻找离生成树最近的未加入顶点k} & R' r- u0 O+ u( K2 r
min:=maxlongint;
' \. U: c* u1 xfor j:=1 to n do
( x" Y$ w; I- P1 `& h9 T$ iif (lowcost[j]< min) and (lowcost[j]< >0) then
" j; a0 W7 q3 Hbegin # f8 |4 @" W- A6 R7 U+ q$ o
min:=lowcost[j]; ' D1 `* w' F0 ]/ ^8 [0 u
k:=j;
a0 q5 I. L' x3 hend;
4 Q( Q q% N5 Q2 [/ c( n) z% f7 mlowcost[k]:=0; {将顶点k加入生成树} + v, O! z+ v; y
{生成树中增加一条新的边k到closest[k]}
" f; U5 O" Z" q, W1 z{修正各点的lowcost和closest值} 3 k3 X, X2 v. k* o0 ?1 Y2 e
for j:=1 to n do 1 E5 g. R3 `, D* H; ?: Z8 y
if cost[k,j]< lwocost[j] then
9 O6 z0 R/ w. w" @ k6 |begin 5 Q2 o% ?3 h: J
lowcost[j]:=cost[k,j]; ' J1 f5 F) O- `* H. {, y3 r
closest[j]:=k; 7 R5 N! v; m9 w4 @* V8 q3 E
end;
/ b' u- T; g: }end;
, W6 ~7 j" i6 Lend;{prim} 2 }! V O+ j0 H/ ~% c& y9 J) z
B.Kruskal算法:(贪心) 4 j3 e& e% [0 V- T" a; m7 B5 H
按权值递增顺序删去图中的边,若不形成回路则将此边加入最小生成树。 2 r' B0 ^! G9 @* `$ x1 E' W7 a
function find(v:integer):integer; {返回顶点v所在的集合}
. C! n) E6 o0 k8 _) M2 G$ W1 c# F( Tvar i:integer;
) L/ q3 Z. E, \begin
( n- l7 ]/ |& g2 Ei:=1;
) \6 o+ @+ ~/ B; V+ n5 S$ K/ j4 rwhile (i< =n) and (not v in vset) do inc(i); 5 L* \" o6 |: C) S4 X& e& ?
if i< =n then find:=i
4 S% U% h* u9 {& qelse find:=0;
5 j/ Q+ B, ^& }end; ! G) d# |0 |4 t4 b! J3 t0 v
procedure kruskal;
+ _, u# E6 z1 _6 O. R' {- zvar
1 R# _+ L8 q [5 }3 }1 otot,i,j:integer;
! Q6 E' {! e7 ~begin
% M6 l6 K4 ]$ @ x: K- L1 B* `for i:=1 to n do vset:=;{初始化定义n个集合,第I个集合包含一个元素I}
5 i8 x a1 h4 d2 g3 I; t9 Z, Np:=n-1; q:=1; tot:=0; {p为尚待加入的边数,q为边集指针}
- k: N% {9 B7 hsort;
6 `( A4 x5 G8 q, p. C{对所有边按权值递增排序,存于e[I]中,e[I].v1与e[I].v2为边I所连接的两个顶点的序号,e[I].len为第I条边的长度} 1 A. H% y( d$ E1 E F( }8 F/ z
while p >0 do \; Y' R4 P" R; B
begin . l( J, O' y: L% p( B5 t6 {
i:=find(e[q].v1);j:=find(e[q].v2);
2 S: B( I' r8 }" yif i< >j then
" I7 j' Z. W% R! f pbegin
, Y- V) {: N' p3 Rinc(tot,e[q].len);
2 P- {! k; w# m2 D. W4 y" \8 \+ C% lvset:=vset+vset[j];vset[j]:=[]; ( v: ~" V, X/ m0 [* S( N7 C
dec(p); % X5 h* F; P2 E8 P4 e* m8 E
end; $ i( h" C0 C2 }' e0 W( p1 w
inc(q);
# ^. {) h! S: v6 mend;
" N. J E$ q% d7 q. mwriteln(tot);
1 v1 _7 I3 ~& `- [end;
9 I0 j4 [% G" M1 X* d& ?3 o. X" t1 r" m+ n6 Y- m
5.最短路径
" P1 C/ z- G% ~" x$ PA.标号法求解单源点最短路径:
' m7 @+ c$ V3 Kvar 4 [$ E: c1 {5 C, q; E4 h+ r
a:array[1..maxn,1..maxn] of integer; 7 G! `0 T9 V3 d, n- P
b:array[1..maxn] of integer; {b指顶点i到源点的最短路径}
7 O( Q6 }- C6 h; L9 cmark:array[1..maxn] of boolean;
& D( d9 q% Q. t) g( s0 t" C! m% P0 s
procedure bhf; % w x) E2 F; J7 c
var
9 ^2 u3 I( V. \ i6 ?+ j* tbest,best_j:integer;
9 ?. D8 v) b E0 K# Nbegin * \3 A5 E6 f! {2 x9 Y
fillchar(mark,sizeof(mark),false); 1 a( ]- S" q9 M- X# q! M/ l
mark[1]:=true; b[1]:=0;{1为源点} " }8 ]4 W7 a; [9 ?+ G3 I3 q
repeat
6 ?' n9 {8 g- Z5 s' t9 |. lbest:=0; 9 a) t6 i. @( H m9 {( g
for i:=1 to n do : V+ R% v( }8 p3 K
If mark then {对每一个已计算出最短路径的点} 0 @6 ]: v' e% q, H$ n/ i( j5 A/ ^
for j:=1 to n do 5 U V8 j- y) c' i
if (not mark[j]) and (a[i,j] >0) then
$ {) H `! p7 R% iif (best=0) or (b+a[i,j]< best) then + p& f6 |3 v" Q5 P
begin ' ]& m) q, s5 f: R! A) i
best:=b+a[i,j]; best_j:=j;
. {% |- Z. o. N/ Z; g. _: r' mend; , ]: z; E; n: ^2 I! A, x6 t
if best >0 then 6 q6 s- x' o+ }3 n# _% X# E+ y
begin
. ?6 }1 P3 {5 L" p5 a+ U: g9 K1 }7 kb[best_j]:=best;mark[best_j]:=true; ) I3 }5 ?, [& a, R7 A1 x
end; 0 S! k3 d4 V6 d" x% R
until best=0; ) D, V5 {! [; d# L, n( p, L
end;{bhf} ; `" J c% A- u1 h
* R) {5 R" f. y. v) t! k
B.Floyed算法求解所有顶点对之间的最短路径:
4 P! D# T4 B/ @3 }1 @$ Yprocedure floyed;
h) h9 t8 b: i1 N% r. S kbegin
7 A: j& M. g6 A8 a8 i0 g- d+ Cfor I:=1 to n do
" v- w' V* a/ D; tfor j:=1 to n do
- h" [' D: l; aif a[I,j] >0 then p[I,j]:=I else p[I,j]:=0;
. v; h( w5 }! U, O{p[I,j]表示I到j的最短路径上j的前驱结点} 3 f+ F7 B, o$ i
for k:=1 to n do {枚举中间结点} C8 s7 m: x. Y( O$ D7 W
for i:=1 to n do \) W/ u$ y0 @8 f0 v
for j:=1 to n do
6 ~+ i, B3 | G& K" o3 `if a[i,k]+a[j,k]< a[i,j] then
P+ q6 Y* Q+ C" Rbegin 6 m) f4 O% X4 B/ e! O$ \3 a
a[i,j]:=a[i,k]+a[k,j]; 8 r P$ n/ K1 W7 Y
p[I,j]:=p[k,j]; _2 {. ]8 z3 J
end; 0 m2 V) j4 X6 n6 E) T% a# ]" |
end; 0 m; ^5 q5 d+ Z5 e5 g+ h! ~
C. Dijkstra 算法:
" q* X7 s( W3 S/ r类似标号法,本质为贪心算法。
% c& I1 C1 T- ^: b4 i% K0 t0 ^$ uvar $ i0 ?4 L9 @9 L# d+ e! g# m H
a:array[1..maxn,1..maxn] of integer; 6 A3 N5 [9 }# T$ u: B) ~3 T
b,pre:array[1..maxn] of integer; {pre指最短路径上I的前驱结点} ! p; j5 L8 q y2 v
mark:array[1..maxn] of boolean; " Z3 k; }7 I, Z# S9 Q
procedure dijkstra(v0:integer);
8 J+ x; F) ^: Y) J' Kbegin
; v" A7 {8 c" Y" \1 ?fillchar(mark,sizeof(mark),false); % s! m3 R; m Q" Z7 i5 }
for i:=1 to n do
8 Q' N9 F. z" @( Dbegin
: ]: A& A% {7 M9 S- {2 Q9 Qd:=a[v0,i]; 4 Z$ R, l3 D, m& T( F) T
if d< >0 then pre:=v0 else pre:=0; 7 ^ |$ k6 F. @' S( n& g8 }+ ~
end; ; E' Z# u7 c0 Q, ~
mark[v0]:=true; . O& \" L; h* B" l7 |' u4 ~
repeat {每循环一次加入一个离1集合最近的结点并调整其他结点的参数}
" `- e4 }9 t& v6 U- wmin:=maxint; u:=0; {u记录离1集合最近的结点}
2 j3 ^* S) |2 A: _ N' d+ }) Afor i:=1 to n do " E, V( ]5 G* E$ w2 m! k
if (not mark) and (d< min) then
) o9 ~7 \( n- `9 Tbegin * x2 a0 z, c6 d% S1 `
u:=i; min:=d; . F9 n& ~% S3 x h0 I
end; 9 f3 S% |! _6 q+ a
if u< >0 then 9 Z7 V8 n% q5 C0 k6 e/ B1 `
begin
6 o$ `7 @' d' V4 bmark:=true; " w/ q' n6 @# i
for i:=1 to n do
" x% u! b! D+ P7 w, D |# [) g Qif (not mark) and (a[u,i]+d< d) then
( q3 f- o8 a' O6 Sbegin
. D6 N1 K- w3 h$ r( \d:=a[u,i]+d;
4 `& m3 k4 k$ {. u( b/ [) R7 Apre:=u; 8 I( h& d0 m3 T) E6 `
end;
/ j+ p, u% y$ \3 h# O8 pend; - U0 i* h0 N. e
until u=0; 7 u5 J8 H: u$ {8 W
end; ; C0 }2 Y# s" O6 X
D.计算图的传递闭包
4 P/ b) m% n6 nProcedure Longlink; " `& g: ?6 \ E
Var / |* a4 W8 F* O% |, `2 y
T:array[1..maxn,1..maxn] of boolean; ' s2 r0 u& r6 R1 }- T$ K
Begin
" k6 s# m8 V" K* W% V8 ]- X# `, T2 |Fillchar(t,sizeof(t),false);
% P& V8 M9 k$ @; ?For k:=1 to n do
( d2 t" m+ z! m. RFor I:=1 to n do
; a4 z' X7 Y, t! s0 ]4 v6 vFor j:=1 to n do ' e w# y: ~. q6 ]7 O+ W
T[I,j]:=t[I,j] or (t[I,k] and t[k,j]); , N# M: H& e6 v: X/ q- C; u
End;
- }! A J8 A+ U( H& ^% Y
y/ W7 ^* R9 Q, L% O |
zan
|