- 在线时间
- 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.数论算法 ; J+ J% P3 d, _( F6 E
求两数的最大公约数
- b9 S2 K& I4 q5 G, L! ffunction gcd(a,b:integer):integer; % y& r4 _, b* f- u5 t* Q
begin
& ~4 a& J! ^' U X& ?* Cif b=0 then gcd:=a ! O6 {2 n& \! j! x1 x
else gcd:=gcd (b,a mod b); 9 J4 B5 m1 t9 O) A8 s( |6 f
end ; / X# Z& p; u* x W O' B. Z
/ `3 s' D) T! g2 a
求两数的最小公倍数 9 i0 T9 T9 d3 m& K
function lcm(a,b:integer):integer; / j- o/ V( b, U e/ B) P7 {6 G
begin
5 V" Y* i4 h& `- ?& Qif a< b then swap(a,b);
& x. q% ~3 k9 X7 R4 t; y# E5 e) B, \lcm:=a;
- |/ R1 S' N8 L4 S. r) nwhile lcm mod b >0 do inc(lcm,a); ' ?! A$ c! h: T0 A" p4 w# ^! O
end; 2 n7 T3 L2 h; l# O9 M% j
7 \( V8 |7 ?+ S8 A
素数的求法 0 W) g s0 _0 ~/ f4 \
A.小范围内判断一个数是否为质数:
{* t* z* e& ~: t% E" sfunction prime (n: integer): Boolean; / x# |. Z6 X: @5 M/ d3 P2 M; t
var I: integer; ( N" n/ m* A- f: I: g# M
begin % A3 `% x7 s* t5 ]/ P1 _* f
for I:=2 to trunc(sqrt(n)) do + V* v% e& v& V4 W. D* @! h
if n mod I=0 then
6 b" g4 i3 z6 A8 k! Gbegin 2 A$ v4 s/ |9 G7 R3 o8 e8 F" D( U
prime:=false; exit; / q) e" N9 f$ d- T6 V4 T
end; ' m/ L: g# t5 U+ f0 X
prime:=true;
- }. |1 z5 K6 d8 D& Yend;
! C7 O/ h8 M$ r: b7 ^& z& R; B9 A" n8 j$ n
B.判断longint范围内的数是否为素数(包含求50000以内的素数表):
" q0 F, {6 g- fprocedure getprime; 4 ]! z- R& ?. e- h
var
5 m3 i1 t3 Y; I$ y$ qi,j:longint; + x5 V9 f, j. H( {" v+ q8 F
p:array[1..50000] of boolean;
3 I- s3 n H& B6 u0 A& |begin - W+ A# [6 o( w# k" U5 u; k
fillchar(p,sizeof(p),true); & E% ]! W- |* M# ~& k1 a
p[1]:=false; " f3 N1 M; F* C. w% o
i:=2;
/ u. n! T1 ]6 I) b( |while i< 50000 do
; T" u3 a4 V6 } p4 T$ J. ?. I; {begin / F* p5 ?; A! }! e
if p then
$ e9 O! P+ T: t2 N' z; ~0 ibegin
* q$ D( G3 K- \ W& [j:=i*2;
& f0 ]6 I; r: v: m5 }! ]while j< 50000 do
6 w: U9 b! Q' Q0 v; O% Obegin 2 [4 R% |% \. M) p" N& O. N/ |
p[j]:=false;
& H# L' _6 @5 [- c! J' einc(j,i); . O6 t* p6 E" U: a; a: o; H
end; 2 p- f' R6 r% q `7 E3 \0 e# T3 k
end; # d3 l% Z# z- y1 l! g2 K
inc(i); # e1 P$ L9 K2 W* Y( ~3 `5 ]9 E w# M5 P
end;
- H) y ]6 E% ]l:=0;
d: b; ^2 f. P2 z2 wfor i:=1 to 50000 do & K! d) l: y! y- O0 z: ]) @
if p then ( f6 q7 R. P7 u; ?, u# p6 {/ @
begin ( q0 B9 N3 [* ~2 d+ e1 Y( A
inc(l);
* D3 a5 X' P, h+ T5 Apr[l]:=i;
& G% M2 G: i, L3 \6 Q3 `end; * j6 w v7 m4 f) P: h! u7 ?
end;{getprime} O& h0 M7 Z* F
function prime(x:longint):integer;
# U3 C4 F6 D1 v: Q& h& {$ U: kvar i:integer;
) |9 ~" Q8 l1 I( G3 u: |! Nbegin 0 m7 g: c" q8 f, A0 G+ N
prime:=false; 1 [1 q$ v% u% C, A2 G
for i:=1 to l do
2 u4 |& @$ W$ M4 A# Nif pr >=x then break 8 C. b; ^5 k, i+ G
else if x mod pr=0 then exit;
: u* p: g8 O' r% x$ a5 r Bprime:=true; 5 R' Z) j' S$ y" M# ~
end;{prime}
9 f7 y3 J7 G+ `8 G: z+ c( L" Q# a0 u( `5 l, m# s- E
2. w- C, `" ?" ^4 J
7 P1 z3 f7 [! t9 ]
3. ) @8 Z; I) Y& _$ J
4 n' n6 N0 e) K7 ]
4.求最小生成树
9 _* P+ N; ]) b: R hA.Prim算法:
5 e% U# r4 \* p9 ]0 gprocedure prim(v0:integer); ) M+ c9 @6 ]* z* _
var
( _* y: y; m0 |; Dlowcost,closest:array[1..maxn] of integer;
* e8 G/ E' Q3 u! r) e$ k. vi,j,k,min:integer; 8 e# k/ U" T$ U9 o
begin * Q: u# x" a! a' Z4 p
for i:=1 to n do
# G, D2 [, r Q9 d0 Z' C$ P N5 |8 |begin
$ z, E7 S9 p- ^. A* Elowcost:=cost[v0,i]; ) U! N2 l0 p# {
closest:=v0;
5 f+ k; N6 b# f mend;
7 b! b2 W X3 [# ~+ lfor i:=1 to n-1 do
4 w; N* P& A, U. N1 G9 Bbegin
M# N. \6 i0 l, n/ F/ o- E# z# a{寻找离生成树最近的未加入顶点k} @. g9 F6 U3 _$ y* ]$ e( T
min:=maxlongint;
" N7 t) p& _) P0 Zfor j:=1 to n do
' z8 h/ `1 _$ x. |* f9 wif (lowcost[j]< min) and (lowcost[j]< >0) then : {+ j) C) V# P9 k/ H% e# D
begin . M8 q/ T. y/ i/ j: a* R
min:=lowcost[j]; ) }/ L) x( E7 y0 p5 W
k:=j; 5 G. l9 E! h& _! i
end; ' o; k: [/ q6 M6 n# D" K8 E! T* y+ i
lowcost[k]:=0; {将顶点k加入生成树} 0 J2 b. A+ r1 E Q
{生成树中增加一条新的边k到closest[k]} $ x2 F( }( J# V8 x8 f
{修正各点的lowcost和closest值} , g" N$ s i7 R% V! \
for j:=1 to n do
$ e* z1 V0 F. uif cost[k,j]< lwocost[j] then / O+ \2 E; `+ A1 v4 K+ ]; t
begin 6 ~& i/ s+ N+ S6 n+ D, c* a
lowcost[j]:=cost[k,j]; : g) @, K! K. q; \
closest[j]:=k; - f4 f% [$ g N# s- o& A- d$ O) h" ~4 ]
end;
1 v& r6 L0 }( {6 Fend; 6 _, m/ j; {2 [+ A" B
end;{prim} 0 ^' ~6 T! k7 m5 {: _8 W
B.Kruskal算法:(贪心)
- @1 Z7 T! ]5 F0 c8 T. k4 U按权值递增顺序删去图中的边,若不形成回路则将此边加入最小生成树。 9 B2 H: x/ e/ ~7 W' e
function find(v:integer):integer; {返回顶点v所在的集合}
$ r/ X( Y7 k9 N; n; T$ W9 I8 Rvar i:integer;
# K% \! o$ v0 r, Z1 I0 {# Ibegin
4 i( @4 w6 b& X. }# k0 |i:=1;
6 g9 `5 G) {1 twhile (i< =n) and (not v in vset) do inc(i);
d8 \& U/ k/ Kif i< =n then find:=i 2 t) N0 r* R% E& u6 h6 u
else find:=0; 6 u% C2 Q! X4 E% N0 [
end;
3 @2 E1 c2 B& o. H: Dprocedure kruskal; 5 R" T$ V. @( X5 z
var " ?: l% s& _, }0 r! e
tot,i,j:integer;
% c( s7 ~+ F( U/ qbegin $ {. U Z# j8 C0 X2 W/ F2 o
for i:=1 to n do vset:=;{初始化定义n个集合,第I个集合包含一个元素I} ' \2 g9 `% @7 Y2 b
p:=n-1; q:=1; tot:=0; {p为尚待加入的边数,q为边集指针} % l5 Y) ]" t9 a) Y }
sort;
. }8 N- X' c, F& f: X& T{对所有边按权值递增排序,存于e[I]中,e[I].v1与e[I].v2为边I所连接的两个顶点的序号,e[I].len为第I条边的长度}
! v, O6 \ W, T) P6 Jwhile p >0 do * W% z4 @( |% `2 F, `/ I/ I
begin % G+ V4 i) K+ j5 |+ P' O( ~
i:=find(e[q].v1);j:=find(e[q].v2); 4 T) d- N! M, w9 V! x
if i< >j then : i2 I1 Y; H+ i3 j; T1 }
begin
+ x1 G8 l) a# t6 S3 ]+ Linc(tot,e[q].len); # M+ T& I6 h, t5 [
vset:=vset+vset[j];vset[j]:=[]; % J* A; U9 r8 ?# U/ a% y, s& `
dec(p);
! }3 J' ^# Q* {! L+ v0 g# Oend;
3 P: J% e) \+ R# X: `/ Finc(q);
! T. E! b* A& I" ^end;
/ o& ]( v5 ] Y+ xwriteln(tot);
9 } _+ ?- [2 n# g1 h K0 Oend;
, e, @/ M7 H% ~$ o( e
. B; x' f; j/ f* V: H5.最短路径 9 d: F' ^+ C7 N
A.标号法求解单源点最短路径:
1 T& G1 {' d, ?8 G& @$ {: ]var
* u6 e. l1 C0 ^0 ^+ A) T5 ]+ z, Ra:array[1..maxn,1..maxn] of integer; M3 U3 X/ i6 T% L Q4 f5 m3 X4 K6 V
b:array[1..maxn] of integer; {b指顶点i到源点的最短路径}
- u( t7 J; l- c! W$ ymark:array[1..maxn] of boolean; 7 P: w9 e! G! T) h9 C8 n. c: Y
# \% }/ t% M6 J- pprocedure bhf; ; O$ d: B$ F6 I0 F s# h
var 1 \9 h' J% K3 H- u
best,best_j:integer;
0 U) Q5 z3 m) Q, f! c+ Z4 kbegin
' W, m, b) M2 jfillchar(mark,sizeof(mark),false);
: n, K# K+ N7 \( X7 G9 imark[1]:=true; b[1]:=0;{1为源点}
1 Y5 X+ c( k2 M' H& L1 grepeat . _+ n( m( n0 r" e( H" b4 ]
best:=0;
1 e G1 U+ I# k3 |$ p) lfor i:=1 to n do
d" }, @( X, b. v' K5 D, }If mark then {对每一个已计算出最短路径的点}
( f! Y( T6 ]' Y9 J; G* m5 ifor j:=1 to n do
@8 \$ H* a8 Rif (not mark[j]) and (a[i,j] >0) then ! [6 I. l0 w b7 G. S2 v" {
if (best=0) or (b+a[i,j]< best) then ' a9 g3 c/ P: h. E: x4 w
begin
0 J2 E( R7 A, F* S. P7 {! gbest:=b+a[i,j]; best_j:=j; 9 d% k& Z9 ^& v. k7 b2 I. U# @2 f, J
end;
+ S6 l8 w; q$ \) p" Iif best >0 then % d1 L R* l+ A: x3 Q
begin
9 L/ `1 L5 P* @! \" {5 ]5 s5 c" bb[best_j]:=best;mark[best_j]:=true; , ^ ^5 b% m) l# r
end;
/ r1 l. M, P7 i7 S) u0 U4 y' ?/ Funtil best=0; 2 I/ R y6 Y e. W, y0 s) V
end;{bhf}
6 ?* | H, g) Z: P
! I9 q9 {' i2 R" z$ f$ |B.Floyed算法求解所有顶点对之间的最短路径: % @: B2 C8 G7 h' q, B/ j
procedure floyed;
( g5 k/ V7 F! q6 tbegin $ W9 W; F9 H3 L
for I:=1 to n do - R4 D/ R6 E' ^+ V4 {+ f, Y
for j:=1 to n do
; u9 I( U g8 h' G7 k0 p& v+ \if a[I,j] >0 then p[I,j]:=I else p[I,j]:=0; - {8 s- @- r; J. T6 w; O
{p[I,j]表示I到j的最短路径上j的前驱结点}
3 b: T0 s: k! q T; N) l, {for k:=1 to n do {枚举中间结点}
+ c4 e6 }6 j0 H/ C7 yfor i:=1 to n do
6 h) ]7 j$ @ {/ s, q" qfor j:=1 to n do 2 {) ?3 S- R: e8 I* E
if a[i,k]+a[j,k]< a[i,j] then
: [% K! N0 ^. ]0 @" }begin
) Y' f. n1 ]/ I, p/ R+ d4 X! M; Qa[i,j]:=a[i,k]+a[k,j];
, K9 h( m. X# n8 ~% P+ r2 B* ^p[I,j]:=p[k,j]; 0 }/ @6 u B( O% x$ t
end;
) D1 i }4 D# ^' B, e. dend; 4 t0 d3 ?) P2 w6 W; U
C. Dijkstra 算法: " a. C5 D% B4 \$ x _7 l
类似标号法,本质为贪心算法。 - F& Q2 u" u0 i/ o* q
var
9 v/ {- D1 E7 ja:array[1..maxn,1..maxn] of integer; , P+ W9 X {* V& M3 G4 Q
b,pre:array[1..maxn] of integer; {pre指最短路径上I的前驱结点}
$ x5 X' d6 i/ A3 N. R. Lmark:array[1..maxn] of boolean; : H7 e" _2 O& ^
procedure dijkstra(v0:integer); 6 p$ m) v" Z: C) m+ ~& `
begin 0 X; E; m8 X" V3 w. a: Z% e
fillchar(mark,sizeof(mark),false); " Y1 ]* }: `$ e) j& J. F
for i:=1 to n do b; x M/ h* ~
begin
6 E! c# l: M! J% w7 td:=a[v0,i];
+ E7 @$ B7 Y: c: g5 Dif d< >0 then pre:=v0 else pre:=0; 3 t8 a9 t2 z& h
end;
2 `+ v; P* ^/ ^7 q) |! wmark[v0]:=true; / ?1 R% E5 w3 G% o( m$ j
repeat {每循环一次加入一个离1集合最近的结点并调整其他结点的参数}
. h- e' [/ g J* m" l/ R% pmin:=maxint; u:=0; {u记录离1集合最近的结点}
) H' \( X9 G3 l! r+ @; X2 ofor i:=1 to n do
9 ]8 U3 C: b: I' A& nif (not mark) and (d< min) then
) |1 x1 I/ G9 P: w* ~- C0 \begin ! e7 Y- P8 Q ]* l- Q
u:=i; min:=d;
, F& Z' U3 Z% c0 U8 kend;
+ C4 _. B- g, kif u< >0 then
7 k4 R9 @2 t e% P' d1 v3 Fbegin
. N' {- Y3 W9 Z& O1 U, T( r& s# |mark:=true; 4 a+ n- M8 `* @5 C. q
for i:=1 to n do
% R0 o- n" L+ H, ~0 @$ Eif (not mark) and (a[u,i]+d< d) then 8 R( O) N6 H2 f5 H" W! [. T2 f
begin ) x2 T0 Z/ b- P7 V3 x
d:=a[u,i]+d; 6 p. ~/ d6 C5 U/ V8 N9 }- h9 ]: g
pre:=u;
6 {; {9 @8 L4 n2 s& i! k+ Iend; 1 s; K. o) g7 p/ ^7 h L
end;
+ W5 S" \+ y3 D( luntil u=0;
6 H: g" D$ W; e7 z* C& W9 Rend;
$ L5 b) ]% ]0 ` zD.计算图的传递闭包 0 o ?7 s: l0 Q
Procedure Longlink; / \6 j; m% T( o
Var 7 D" t( Z7 k r: M5 s3 x& M
T:array[1..maxn,1..maxn] of boolean;
$ `+ U: X! S% G7 fBegin
: V0 F6 ?6 l5 xFillchar(t,sizeof(t),false); 6 o1 e5 I- U$ Q) f
For k:=1 to n do
3 R/ V3 h# z0 W7 u1 w1 W! HFor I:=1 to n do * u% ? \: f. k( l
For j:=1 to n do
6 _$ f+ o6 j- C; xT[I,j]:=t[I,j] or (t[I,k] and t[k,j]); , T5 [' G) E! O7 H; q6 h
End;
1 \5 a ]2 d% D" f6 A
9 x! J! V- T8 O, R" Q/ x |
zan
|