- 在线时间
- 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.数论算法
0 C6 }2 Z. e' R% r9 H3 ?3 |求两数的最大公约数
* C. T: y# ]' `. b, w' Yfunction gcd(a,b:integer):integer;
! ~( u) J) r/ g: b0 y# Rbegin
5 F, H0 r( v* S/ J/ nif b=0 then gcd:=a
2 l- M$ u, u8 L0 z: f4 q8 n" relse gcd:=gcd (b,a mod b); . b% R0 M% C% G1 R; g( ?* }
end ;
1 }4 S R l8 a& S0 ]4 `- N$ W. d$ G1 i; P! ^
求两数的最小公倍数
& q1 T) U+ ~ l' I0 M ]- P" O1 Y5 mfunction lcm(a,b:integer):integer;
% e0 `' q4 H( Xbegin . b( H4 c( T+ |0 P4 z- y( X! M8 {
if a< b then swap(a,b);
2 J6 C" b3 H# y2 G0 d+ ylcm:=a; . s+ [+ A# B+ R
while lcm mod b >0 do inc(lcm,a); 3 @2 x, u7 ?: @
end;
( G5 L( ?: F* y- E4 } W* \/ e+ B: a8 E, V# J
素数的求法 ) o2 m5 W3 a! k" l- v
A.小范围内判断一个数是否为质数:
1 l+ g% L7 h! d, j% E% Tfunction prime (n: integer): Boolean; 7 l; C% |3 z" K, n
var I: integer;
' f% R$ X. C& @ Q3 Tbegin - K z: @6 u7 w! h. W: z; k
for I:=2 to trunc(sqrt(n)) do ; N7 @0 i: O3 h
if n mod I=0 then
: ?7 ?' S9 V( U+ G+ U6 J% lbegin / ^! H9 s, U- r8 A' _7 F. d
prime:=false; exit; ! v6 C% V$ |, | K; j* V& @9 k: p
end;
: `4 K3 W. j/ V: _1 R& Jprime:=true; 8 ^* m) n9 Y) H; Y0 W4 i9 j
end; * R4 {" q( C/ @7 _/ \$ F
! y' {4 N1 `3 ZB.判断longint范围内的数是否为素数(包含求50000以内的素数表): 7 c& s$ W6 d5 a' K6 w3 Q
procedure getprime;
& J: z, j* A1 p# @' \/ ovar 2 I% w w; F% P( L. E. L% F1 [
i,j:longint;
) |! X+ o- r6 |7 K: s& u: e! rp:array[1..50000] of boolean;
& q ?- ]7 o& n \% @+ Fbegin
7 s7 j; `- k% l9 e; o& h+ hfillchar(p,sizeof(p),true); {, L" F+ {1 j! T3 g
p[1]:=false;
3 a: {1 T& I5 h) H2 Wi:=2; & Q' w6 u( S; j. A
while i< 50000 do
n- e9 s+ r: r. z kbegin
9 M. b( U1 a7 Nif p then
! e1 J. H/ p( J# }; Xbegin
8 a2 M" A1 @* L; `' Zj:=i*2; . D+ s; @1 Z9 X
while j< 50000 do
( ?( B6 {1 V! @9 O1 Wbegin
3 r4 N' | e" }2 Xp[j]:=false; 8 G4 h) B4 h' z, H# k6 P; G6 v4 f
inc(j,i);
3 v/ K6 F! T( p& _( C$ Pend;
3 v' O# }1 q6 y1 _' W. f) ^end;
# X- E. K+ p, O) B( t" J1 Kinc(i);
$ B# K* X, R E/ j6 aend; 6 j# w# {* T) [2 u
l:=0; # N4 G- p/ p7 Q6 o
for i:=1 to 50000 do
/ f; d& Z+ _( k: S' q( f. oif p then 7 R9 E1 `5 Q5 P
begin
1 I8 h$ Q( U9 `" P- _1 ~$ q$ Xinc(l);
) j2 ?( b" J0 B1 K x5 [pr[l]:=i;
& W9 w4 {$ Q- M/ Vend;
- o' X: i8 W8 N9 ~end;{getprime} % ~. C' x8 O0 O, q' ]! x
function prime(x:longint):integer; 5 E" \9 d7 X; U! B% k0 C0 O" R
var i:integer; - |7 d4 ~: L/ ~. t% N: H! U
begin s- r9 A3 L- _0 Y: X$ @* V9 X4 p7 i
prime:=false;
" V, J2 i' o d( j! Nfor i:=1 to l do
: U8 Z% T) j! B- j0 u: a! Nif pr >=x then break / U3 H6 ]2 F: B" T4 `
else if x mod pr=0 then exit;
/ L* Q* h3 w" |8 Hprime:=true; 3 O1 e, d7 m h: u( T
end;{prime}
$ G2 d0 c9 Z& \9 f9 R! e! Q9 q9 w( H3 g
/ n6 A: S. P* y' l5 s2. + ?8 S% z9 f( }4 B6 z
, Q/ g+ o' X; i4 w% W1 ~3 [, _6 n8 @5 O3.
* v; z6 w/ W% H5 w# @: Q
' z C* x8 o; H6 H2 K4.求最小生成树
, N9 R# L7 b. n" G& n; [A.Prim算法:
, j- P& a2 g# }, ~procedure prim(v0:integer);
! l, ?+ A! O- D8 @& ]7 R: svar 4 I- \, m. O z( u0 J
lowcost,closest:array[1..maxn] of integer;
+ O+ E. d+ i2 `7 T& wi,j,k,min:integer;
3 B' q! s0 G! A# E: J' Zbegin
! y' Q( F: J% X) J( A* y: b& Lfor i:=1 to n do + L4 O0 v( ~1 B
begin g6 h- O* y1 q! L! `
lowcost:=cost[v0,i]; $ b3 ?1 B& d- Z h
closest:=v0; . O$ H, P: g7 \& e. D+ N
end;
& u) |7 @# o q' a2 _9 T# Gfor i:=1 to n-1 do
! n6 b4 r! O7 ebegin
H$ G+ V! y% E- K- j{寻找离生成树最近的未加入顶点k} 3 i& m3 `5 u7 H4 r( J) k
min:=maxlongint; . A t( u" d- d+ M: s
for j:=1 to n do " S4 J) r2 r7 o) C. P. ~
if (lowcost[j]< min) and (lowcost[j]< >0) then
6 @" Q4 M! T- t% Mbegin
1 h# Z+ }; W3 a1 _- d* I5 N0 P4 Kmin:=lowcost[j];
) b: j" l) S- O2 qk:=j;
0 d# }4 a" x4 m$ {' u: Hend; / S9 _9 @, J. H
lowcost[k]:=0; {将顶点k加入生成树}
% S" D- ?3 A4 u5 n{生成树中增加一条新的边k到closest[k]}
( r2 v: _0 o$ f{修正各点的lowcost和closest值} ) V. c+ j8 ?3 B1 h
for j:=1 to n do
1 L# b1 V6 F; |+ Gif cost[k,j]< lwocost[j] then
( ^" w2 b5 w/ v& {8 O3 d7 N1 O; abegin
) B' b, |4 M% _! B- u% K2 D/ Llowcost[j]:=cost[k,j]; ) j' `+ j% w6 X
closest[j]:=k; 1 q: j' Y# y" q# z# c
end; 5 _- l3 S% p5 F7 G! S1 E' E
end;
; P- |+ P$ F% d/ x- |end;{prim} 3 G9 k( ^! N. ^+ ~7 y
B.Kruskal算法:(贪心)
0 o, d B+ w: w% |$ l5 Z6 U3 y按权值递增顺序删去图中的边,若不形成回路则将此边加入最小生成树。 ' h6 u$ w, ]$ q8 ^/ U
function find(v:integer):integer; {返回顶点v所在的集合}
b# Y5 j! p% ^# |7 ~0 Wvar i:integer;
+ z2 |! F- \6 w+ K- |$ I2 tbegin [. ^8 ]2 J b7 Q! l
i:=1;
3 p; f- t" J- c/ cwhile (i< =n) and (not v in vset) do inc(i); 4 Y4 O3 j0 @5 [7 j4 o1 e8 L/ e
if i< =n then find:=i S, W# }4 V0 D; v4 C# I9 j" C
else find:=0;
* U% |2 Y; D5 j! w5 Y' ?end;
- E1 f4 R3 y% a$ c! s# i( m) Yprocedure kruskal;
) X* Q1 K0 ]* E' a fvar
8 L! D; N" v; Q' u7 Q0 U4 @. P Ltot,i,j:integer; 2 H( t, @+ T t6 {
begin ; L7 {) J' {6 h$ T- Q1 x+ \4 l
for i:=1 to n do vset:=;{初始化定义n个集合,第I个集合包含一个元素I}
, T' Z1 a0 f0 P) j1 Vp:=n-1; q:=1; tot:=0; {p为尚待加入的边数,q为边集指针} $ q9 m( o, C$ }' O; A
sort; " x* [ h ]) }- `$ j6 j
{对所有边按权值递增排序,存于e[I]中,e[I].v1与e[I].v2为边I所连接的两个顶点的序号,e[I].len为第I条边的长度} % ~/ V5 o1 m* i
while p >0 do ) M/ y2 o0 {9 O6 `( D6 t3 A: i! G8 L
begin + s" T* y5 V+ s# {
i:=find(e[q].v1);j:=find(e[q].v2);
/ I* A5 G) Q! W" D" m1 c0 uif i< >j then ) g% b" r7 o. U. V' I$ ?
begin : J0 w- {" d/ P. T: k
inc(tot,e[q].len); " E% Q0 F# ~: Y4 t% @; i. {
vset:=vset+vset[j];vset[j]:=[]; 7 {5 L; @: B" P5 U
dec(p);
( o S2 [5 l9 }: e {9 F' oend;
' {: h, A) V5 E: k8 P' ^9 Ainc(q);
% `# S) W! o; s4 Y2 Z" s/ _end; - k) G# a4 P: _, i4 m
writeln(tot);
1 W( v( D" c2 q$ j$ N+ nend;
: e/ ]7 [# X+ U1 w0 v
& q5 [ E. q& V, F$ S! q5.最短路径
1 {0 m( u, ?8 L4 jA.标号法求解单源点最短路径:
' ^6 H% z: K7 E o3 Z* A/ M f1 bvar
6 C/ Z+ _; z3 [3 l" Ba:array[1..maxn,1..maxn] of integer;
% R& a" L' D5 U( Q0 a1 m" O& ~b:array[1..maxn] of integer; {b指顶点i到源点的最短路径} 8 X# O& ^- H; ?2 e
mark:array[1..maxn] of boolean; 8 g' C; q. l2 q& U" F
; ?. l, c! S. A+ l9 T
procedure bhf;
9 z" V4 S- R3 svar
( r) y8 s% Q- M& sbest,best_j:integer; 1 b' w3 L) Q' V: ]1 Y9 h# t; a
begin 4 Y' `. z o3 Y. W3 }# z3 [& w
fillchar(mark,sizeof(mark),false);
; M1 }: R& c/ E# S' |. Imark[1]:=true; b[1]:=0;{1为源点} ) t5 |+ }* }6 P8 h
repeat
8 h8 F7 y [* F* H! e1 r* b+ g( M7 qbest:=0; / v% y/ j4 M1 a1 U
for i:=1 to n do q6 k9 `2 a' X8 g" b& [9 k: @
If mark then {对每一个已计算出最短路径的点}
/ J7 D# i9 x1 rfor j:=1 to n do / I# a5 W3 M: i
if (not mark[j]) and (a[i,j] >0) then
. e" J# a% m- i! }( {( ^3 l6 j( ] ~if (best=0) or (b+a[i,j]< best) then
% j0 K- G5 U* z$ Z+ }0 tbegin
! h) T( J% d& X1 s# o$ T$ y8 ebest:=b+a[i,j]; best_j:=j; 5 W, @3 R" [+ O$ q9 M* e
end; , r7 p z; M+ ?% h4 {
if best >0 then
( @7 j3 K; O- K3 ~( m; Mbegin
8 F$ d: L- B8 T$ Yb[best_j]:=best;mark[best_j]:=true;
( _6 S4 ~% v; ^3 ~1 ]$ W, \end;
! O& ~" v( ]" ]) ?4 t9 m" g5 Ountil best=0;
5 n% a8 X, _. E/ {3 `end;{bhf}
8 J5 O) m. i( p, p. \+ [$ }, e5 e- t( B
B.Floyed算法求解所有顶点对之间的最短路径:
" s2 P: o* e1 o9 n( t% Nprocedure floyed;
! W: @; V2 m6 p8 ]7 b4 vbegin - l* v% A$ z2 x
for I:=1 to n do
: I! `# J# W- G* ~for j:=1 to n do 6 {7 ~& V7 | ]5 Q$ \. O2 s
if a[I,j] >0 then p[I,j]:=I else p[I,j]:=0; % ~' Y" k* }% {
{p[I,j]表示I到j的最短路径上j的前驱结点} * w/ h2 K- j) s; v( ^3 r8 g6 M% T
for k:=1 to n do {枚举中间结点} - F0 p( W3 E8 K$ E% Y4 N) z# d
for i:=1 to n do 8 ~' B, U4 B% K0 Q/ `
for j:=1 to n do
. h$ H& s! @) ?if a[i,k]+a[j,k]< a[i,j] then " t/ s6 @3 C' z+ ^, W9 Q
begin / D3 [: I4 l' z
a[i,j]:=a[i,k]+a[k,j]; " [; R$ H0 M# m, k9 T8 D8 c2 \2 z
p[I,j]:=p[k,j]; 1 ^9 w/ I8 e- a
end;
* S) K- E* ~/ [end;
/ t3 g- \ f, }' R) A' K; kC. Dijkstra 算法:
+ q/ V8 F1 w: h9 i类似标号法,本质为贪心算法。 % g3 f1 s, M& a, _" s8 [5 o
var 5 l8 p \# V9 D" s: G1 s
a:array[1..maxn,1..maxn] of integer; 5 l2 x/ @$ Z8 E6 P, q: e9 B
b,pre:array[1..maxn] of integer; {pre指最短路径上I的前驱结点} $ P/ b1 C) p4 d& Q4 }5 \
mark:array[1..maxn] of boolean;
. T, X- F7 w' r0 P$ y Bprocedure dijkstra(v0:integer);
1 F5 D' b! b; a* f( H% cbegin
) s" W! H, {8 V4 V# L: [- Tfillchar(mark,sizeof(mark),false); $ R8 J1 y- K. D8 F$ H O3 d5 h
for i:=1 to n do $ `* ~; Z" n4 p9 b) A
begin
( M6 B) F# D- u8 Y) x# ~/ b6 md:=a[v0,i];
: E$ X7 {( F/ J( i1 w9 n* Fif d< >0 then pre:=v0 else pre:=0;
, V; O# R( s' Q; `: Xend; # @" _4 z! T) T4 o- Y
mark[v0]:=true; ) u' S$ Q6 d- F: O+ V
repeat {每循环一次加入一个离1集合最近的结点并调整其他结点的参数} & |8 b' D/ ]- _
min:=maxint; u:=0; {u记录离1集合最近的结点} - @; E: M; J! r( w( w+ v0 n# t
for i:=1 to n do
! E1 T& A' ^ |5 r5 g0 eif (not mark) and (d< min) then
: P4 n M7 }# t V" y9 w, Z" y/ Qbegin
; {( `- |: R# e: ]6 `0 M; r3 }$ Ku:=i; min:=d; 4 Y- m5 B: F) P5 [
end;
0 |- v( o4 H2 [ Hif u< >0 then
* c7 G8 b, p0 r3 h9 ubegin ; a' w5 X8 I/ Z3 ^# J
mark:=true; . {+ U* Y( ]# d- Z: ^
for i:=1 to n do # V' J: a x# U3 U
if (not mark) and (a[u,i]+d< d) then ! f9 m* G# R' S6 X
begin
5 o2 i( r! H# k+ i- E+ D# `d:=a[u,i]+d;
1 c( i/ W; ?. S% j! N/ |pre:=u;
6 b4 _" @! ~, y+ H/ G" ^end; # z( ^8 }1 X, F6 y
end; + w, ^& J9 \ u; V3 h+ C+ `9 K
until u=0;
U* C5 }2 S/ l! g& g$ N9 a5 eend;
0 K6 Y0 r' ^# L& i+ G% ]1 H- Y( N2 ]D.计算图的传递闭包 C- y, m+ I' G X4 y3 E$ x; Q
Procedure Longlink; 0 U8 w1 p! a7 y* n; ~" t) i
Var 3 j9 o6 C( Q3 i3 U; g3 F- P
T:array[1..maxn,1..maxn] of boolean;
9 X; W& J& @0 ?' uBegin
* o4 M7 a7 f1 t1 @; t' `Fillchar(t,sizeof(t),false); 9 v: n- j( \3 G/ X+ Z X6 U, A
For k:=1 to n do
& O8 @. S, u/ z p( G- |% FFor I:=1 to n do $ x: m! f: V" g. e# M6 v2 _
For j:=1 to n do ! G" z2 F Q& J4 T) h- `. K3 m& {
T[I,j]:=t[I,j] or (t[I,k] and t[k,j]); 2 b6 L2 e. y# K( h
End;
0 ^3 N p+ k) I; ~1 U- R( U- c
* t5 A* B6 a4 G$ D |
zan
|