- 在线时间
- 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.数论算法
^2 x' E7 W! n* Y0 O! J7 R3 U求两数的最大公约数 # f& ?! D9 z9 j/ f
function gcd(a,b:integer):integer; 1 w( K7 u9 k% y9 P
begin 7 y& ]; ] d! |
if b=0 then gcd:=a 2 ~# d) v% g! z9 x& g: R( I4 ^
else gcd:=gcd (b,a mod b);
9 s" C& z, E! j5 S$ t4 _end ; . I% I1 T4 B% c6 @; H; W
, N# L' ^7 z# |/ h5 ?: b求两数的最小公倍数 9 E5 s* R* @ ~, Z
function lcm(a,b:integer):integer;
% Y/ i% y0 P4 ^$ Rbegin
8 R! |9 p" o$ Vif a< b then swap(a,b); / X+ Q% o/ |* o# b- f |0 t
lcm:=a;
6 z$ l( k+ P3 e D7 U+ ~3 cwhile lcm mod b >0 do inc(lcm,a);
/ m: I' d; k* T. h/ o; }5 y+ ^* Send; 6 n: q7 y( }$ m3 x# G
1 F' Y) l8 Z1 M素数的求法 8 \6 ~4 G% e" y0 T# b* d9 Y
A.小范围内判断一个数是否为质数:
; Y9 o5 w4 l) f& o( z0 }3 E" k8 E% jfunction prime (n: integer): Boolean;
) G* @* z* ^. ?4 @& {: ~& k& Kvar I: integer;
) H! i; B! U3 c6 \; P& m/ u3 ^& d+ mbegin 3 R- a. j1 w# Y: w* X
for I:=2 to trunc(sqrt(n)) do
. f" \ V" ~: e# d5 ^if n mod I=0 then
3 _0 d T T# S* zbegin ( P6 u7 r" G8 p) O* r" k W, ]
prime:=false; exit;
/ P( z! K g- W- x$ m7 A7 ~ Zend;
3 f+ y# x) s: T; {* Rprime:=true;
0 s1 e) G+ E; S/ U4 R0 A1 q1 U( d! |end; / V7 Z8 _3 V+ s8 g( A: P$ T
2 C+ d5 O) ~7 } g6 L
B.判断longint范围内的数是否为素数(包含求50000以内的素数表):
8 \2 Y2 U( `, m' pprocedure getprime;
! e+ w* C8 b+ i2 z$ x \var
' z- L% w, N8 j" `) q5 Ri,j:longint; 0 U h: b3 x8 a6 K# n0 D" Y j8 l: b
p:array[1..50000] of boolean;
% P8 }' d5 N* ?' fbegin + C: b# h+ F( d7 [
fillchar(p,sizeof(p),true); * y0 L7 [- D ^% D/ O( C6 N. O
p[1]:=false;
+ w. d. i; s2 k# K' y. \, D5 ui:=2;
8 F5 v5 `# R& b- A3 ?2 {+ vwhile i< 50000 do ; t4 n% J/ w) k. V7 p, r6 R2 Y& h
begin
* }2 n$ m: D2 U- Kif p then
. f9 f" C0 N& z* ~begin
/ A/ A, @( B1 hj:=i*2;
3 y, W4 n9 z& n' k2 nwhile j< 50000 do
, R1 M5 {& ^* P( s# qbegin ( F0 D+ Q$ }& r/ s
p[j]:=false;
& a) E6 j* }$ |+ n9 q/ ^inc(j,i);
- u3 @2 u( ^7 d$ Vend; 4 W0 D T0 g$ s7 W
end; 7 p) S* q% U7 K4 R7 Q# _
inc(i); 5 v2 |2 @3 Y3 ~, P2 [
end;
5 U* ~1 m3 v* C1 Al:=0;
/ T3 D6 L" M: S* ]$ J T9 n1 dfor i:=1 to 50000 do
6 ]+ {# d/ J- M, Vif p then
h9 }9 B5 w% T3 C5 T H+ Y0 ^begin ( W. E# T6 R s9 x) t. A/ _
inc(l);
3 L5 Q. ^7 w1 b! T+ rpr[l]:=i;
5 I3 f( M" p. T2 D- F- G" Hend;
/ F* p1 q5 h6 D. @3 ~; P$ f7 R2 Gend;{getprime}
9 {5 i0 X: q( H. Y* efunction prime(x:longint):integer; ) y. L' `( w# s- U! W
var i:integer;
* H0 a1 q7 l3 i* _, sbegin
# O* u( Z8 X% P9 tprime:=false;
) t6 Z/ z5 I. J9 | Hfor i:=1 to l do
* |4 E ?! z7 l8 L: g) @8 ]( q3 lif pr >=x then break . s- m, e, _9 I& c: W I
else if x mod pr=0 then exit; & y9 p7 s6 p [1 t9 X7 g/ H
prime:=true;
. {' P" p4 s# E0 ~1 @end;{prime}
6 S9 r/ t" K, B: M* c+ U- y
: c7 Z# k9 A) x7 X# T2.
1 M1 L" s2 }! f1 G( j: X( F9 Z# ^ M4 I
3.
0 o( b' X4 v. C6 D0 r1 q& X0 T8 d4 e9 H& G5 y, D, l
4.求最小生成树 ! v, @( R7 |2 I6 o8 M" x4 ~$ y
A.Prim算法: E d: `/ @' @# ]
procedure prim(v0:integer);
* `+ c2 N" L$ ]7 B" xvar
& h# Q# k, ?( w# L+ Wlowcost,closest:array[1..maxn] of integer; 8 f6 I' P9 d7 \+ m" e8 S
i,j,k,min:integer; % P2 G5 m# H D2 f' z
begin 8 p6 l5 ~' \" Z. q* C) u# n
for i:=1 to n do
* Y% |+ R+ Y: K4 I4 i& {# ?! Cbegin
' N+ o& f* S$ ^' E! ~+ Qlowcost:=cost[v0,i];
% v2 F! P |/ H$ b' E+ xclosest:=v0;
) ]9 G2 s5 ]9 s* l4 }end; 0 x+ J. S* [( p8 S7 h
for i:=1 to n-1 do
2 H% P" ]2 U7 V; |) h) x' ^4 U0 G9 p3 Ubegin % ?; u8 x& F5 O9 N, y
{寻找离生成树最近的未加入顶点k} $ m9 t/ f. F7 Q: K& L% [
min:=maxlongint;
7 X2 [ x' B7 @' ^3 ifor j:=1 to n do
& b/ o/ N0 A# wif (lowcost[j]< min) and (lowcost[j]< >0) then : r7 A# L6 l) ^# Z7 f) L7 E1 Q0 b
begin : p# e# D" x8 v$ p6 n! M+ ^
min:=lowcost[j];
; B7 P5 I% E n+ y, F8 z6 G3 Kk:=j; . ^" g" f- R/ X9 Z/ }
end;
( v% X* u# F S. \lowcost[k]:=0; {将顶点k加入生成树}
/ I) k* F" O0 H6 D{生成树中增加一条新的边k到closest[k]} $ Q/ W8 d* m" {1 ? Y
{修正各点的lowcost和closest值} * ?, ?$ O" D# S4 i* T5 u a. u
for j:=1 to n do
+ a% ]6 X1 B2 G. `; jif cost[k,j]< lwocost[j] then
3 b% w/ ~" D$ rbegin Y$ Q% B8 S& P# _5 v
lowcost[j]:=cost[k,j]; 7 C) \% T0 r/ V; `6 {" |; Q5 c' v
closest[j]:=k;
3 B& d O4 c$ r4 S2 O' u6 Q: K) ]$ Rend;
8 i9 o* p3 E8 P) Z {: {+ Lend;
9 L9 `+ s: f# P- W }* Tend;{prim} ; L0 a, K8 \; K: b
B.Kruskal算法:(贪心) 5 S9 F) N" h6 x( p( @+ c# l$ q
按权值递增顺序删去图中的边,若不形成回路则将此边加入最小生成树。 + X3 _; D) U9 }
function find(v:integer):integer; {返回顶点v所在的集合}
% c6 t$ q' E* E- f8 k7 ]var i:integer;
& D: i, _5 E$ {% ~5 Bbegin " w A X/ n9 |4 Y6 B) o2 O( S
i:=1; : P! d) f# I+ ~. [
while (i< =n) and (not v in vset) do inc(i);
+ C2 }* S3 R7 ^8 R) X* jif i< =n then find:=i $ F$ u1 }/ W& `5 o
else find:=0;
( W6 _' N3 s( n$ d, y0 send;
& f5 ~$ F6 C6 Pprocedure kruskal; * Y0 X2 y4 v1 o$ n" d
var d V+ U; l) j5 x. S2 T
tot,i,j:integer;
; p3 j$ \+ S* ?$ ]4 F0 \- nbegin 7 @% z( _ w3 |4 K. Q
for i:=1 to n do vset:=;{初始化定义n个集合,第I个集合包含一个元素I}
, |8 U o: C# D& G# xp:=n-1; q:=1; tot:=0; {p为尚待加入的边数,q为边集指针} . r/ m& }& s" f0 E" u
sort;
L5 f2 o3 v; g$ T" v; k0 E{对所有边按权值递增排序,存于e[I]中,e[I].v1与e[I].v2为边I所连接的两个顶点的序号,e[I].len为第I条边的长度} & F4 y& h1 K+ \( b
while p >0 do 4 z4 f7 e* z) ?* Q
begin $ a; g( {8 d* [# s
i:=find(e[q].v1);j:=find(e[q].v2);
- m" N2 Y ? N- V7 tif i< >j then
/ s d# R2 \* m X2 z% xbegin 4 H3 _, H+ w$ X8 V
inc(tot,e[q].len);
4 F& m* `% v( W; \ _0 Fvset:=vset+vset[j];vset[j]:=[]; 9 L' f+ m$ O/ q: w
dec(p);
7 W& D6 z+ m9 ~. I5 eend; * l) J( K. E4 r( U* t: K/ Q, ?! c
inc(q);
2 m# Q+ Z6 K* A6 d. p Tend;
- c& u: ~, O3 z/ D0 r) [writeln(tot); % u u9 b7 z, u$ l
end; , ` g; a0 ~! P1 {
' ]$ R" V3 e/ J% q5.最短路径
& W- A/ a/ w! }) `% q$ tA.标号法求解单源点最短路径:
Y, Q9 Q: _4 Z5 t4 Kvar
6 K9 r" O3 W+ P/ m1 e1 Oa:array[1..maxn,1..maxn] of integer;
: ~) {# D: U% Q9 k5 D5 hb:array[1..maxn] of integer; {b指顶点i到源点的最短路径}
; N0 ^+ ]; g7 {# u# Ymark:array[1..maxn] of boolean; 9 z' W+ w" a; {4 G1 q" K0 M) B J. T
. ]- y6 E4 r- q
procedure bhf;
) m P' J$ O8 ^var ' i& L: G' Y) L: x. b2 k5 a
best,best_j:integer; ' j3 R- [( @& ]0 F
begin 5 g- B; T0 V' t- E% f8 T
fillchar(mark,sizeof(mark),false);
5 Z0 h# c* h" }7 ~mark[1]:=true; b[1]:=0;{1为源点} : z" [8 c: o* I( d `$ O9 H5 w5 {
repeat + h) p% |: p! h6 ]7 C1 |4 G) L
best:=0; 3 v1 q; p& J! ~4 q% F
for i:=1 to n do 8 v0 f/ Q. k& o2 |$ d
If mark then {对每一个已计算出最短路径的点} * h; U% e+ m) ^
for j:=1 to n do ' j x; v+ q$ s& S5 @+ z, c5 ^
if (not mark[j]) and (a[i,j] >0) then 1 l5 |8 Y# m* J! f1 ?
if (best=0) or (b+a[i,j]< best) then 0 m& m) C) S; X
begin
1 l5 J1 J" N, N' @: S2 p: mbest:=b+a[i,j]; best_j:=j; 4 |: E$ `( a/ S" X' t( M$ `" S% f
end;
4 _/ f' U/ z3 {if best >0 then ! q \4 s' T2 C/ q S
begin
! G, g9 @$ P; v/ _7 }% {" N gb[best_j]:=best;mark[best_j]:=true;
9 ^% p3 N* X- ^6 z* @" P3 |end; 0 t$ X* M1 Y; p E6 I
until best=0; ! V- _9 O, Z- ^* L d4 [% L
end;{bhf} / W. F& ^9 G; o8 N" a
( k& `$ {. Y) [4 m: C6 k2 h# Z7 WB.Floyed算法求解所有顶点对之间的最短路径: 9 J2 E: y& B$ q$ \) F' a& X2 M
procedure floyed; ( D% \1 a6 {$ ?( Q$ G$ z. {0 p& s9 ~0 M) i
begin
4 M9 Z i: A3 J6 jfor I:=1 to n do 0 A! ?* d9 C! J' \/ Z# h
for j:=1 to n do ( B; c2 Y4 P: Z9 D _* l
if a[I,j] >0 then p[I,j]:=I else p[I,j]:=0;
( d i9 o2 B/ i8 j) e+ Q, i{p[I,j]表示I到j的最短路径上j的前驱结点}
, `3 F6 M* G p6 Xfor k:=1 to n do {枚举中间结点} 5 X8 N: c0 L+ s- ^
for i:=1 to n do / A/ L( B) ?& v' x2 @
for j:=1 to n do + n3 [+ l- O& F$ `7 t+ E% \
if a[i,k]+a[j,k]< a[i,j] then
4 j* a' ?/ c4 A, \/ P3 Nbegin
$ l0 i& A7 j0 Aa[i,j]:=a[i,k]+a[k,j]; 0 ^- c: d7 t( N2 q1 h& ^7 t
p[I,j]:=p[k,j]; ( U- s. k. |# m) b/ S6 m8 h: }
end; , r9 R/ K; n) d% S
end; ' y5 d6 D0 d2 V$ r" o
C. Dijkstra 算法:
0 \ q8 q4 `' C. A# k( X! s类似标号法,本质为贪心算法。
1 \, } w, x# Wvar
& T& \2 C5 X9 F# `8 Ua:array[1..maxn,1..maxn] of integer; ) _ L# w( {* N5 O" o
b,pre:array[1..maxn] of integer; {pre指最短路径上I的前驱结点}
/ n- }& X4 ^1 C {* H4 Pmark:array[1..maxn] of boolean;
# S H! X+ {3 \" g0 H3 a5 zprocedure dijkstra(v0:integer);
3 S" s# r5 {, Abegin
0 T$ v% Y! c7 K" w; d3 h! Y7 Qfillchar(mark,sizeof(mark),false); ( @$ C8 V! Y7 M& v/ K
for i:=1 to n do
, z B* F/ O6 f4 {' r4 Rbegin J D7 c+ c1 I6 d* o
d:=a[v0,i];
- `8 R/ j d* n- x+ u3 m) qif d< >0 then pre:=v0 else pre:=0; # {, W! i1 U! U; M5 P5 Z
end; " K6 I( P7 R' d6 v k
mark[v0]:=true;
8 y, v2 S5 W) _; M" Q2 i7 Drepeat {每循环一次加入一个离1集合最近的结点并调整其他结点的参数}
( g1 b3 T+ b0 x$ Z! y- ]min:=maxint; u:=0; {u记录离1集合最近的结点}
( B* U: R4 Y4 J: L, D2 ~for i:=1 to n do
/ p, a9 I' x" O7 m# Bif (not mark) and (d< min) then
; h \2 y5 X xbegin 2 h# l9 v1 o3 n' j
u:=i; min:=d; - j7 [! i; G. U$ a3 j
end; 2 `. \* W% o) M% X
if u< >0 then 3 d3 l# R) E2 ]/ ~1 k
begin
/ p F! J6 E4 w, R5 O" }mark:=true;
1 J" \( A3 T0 K: Pfor i:=1 to n do
1 L- B; a7 c/ L0 V( F, {if (not mark) and (a[u,i]+d< d) then
7 F! o6 @4 F# L1 Q$ F4 N3 `% {begin
% k8 G2 i) y+ j( @. E5 Q2 _d:=a[u,i]+d;
% R; J* z0 A1 l) vpre:=u; + n* n6 P: n0 a2 ?$ F
end; & q: ~) _- \) v0 [3 b+ @1 y9 L
end; $ V9 F1 j+ ?) [% i& _
until u=0; " S/ Q( c( P4 z3 ]0 t* ]5 D- F4 ]
end;
8 L7 l, |& G6 X( s ?. Y: ZD.计算图的传递闭包 d' n7 k3 ^& J! T* a, S
Procedure Longlink; 2 ?. M0 i- Z% F L0 [
Var
7 |' n0 H4 X( ]" |0 S+ z# w% yT:array[1..maxn,1..maxn] of boolean;
# Y0 I L M3 Z |$ vBegin
( i6 @! n2 O) M! X5 l# `5 J# A5 EFillchar(t,sizeof(t),false); ; ?; c% G) |) p e% D. f
For k:=1 to n do ( U! \3 G( D/ Y N- B# @7 u" @
For I:=1 to n do : @1 ?$ r+ A& i# v z4 }
For j:=1 to n do & T: m% ?; @9 w; T. q
T[I,j]:=t[I,j] or (t[I,k] and t[k,j]); 8 }/ ^. w; Y' d( c( e5 r
End;
R% P0 \# g4 k" u" v9 A f: o/ Z+ r% f7 J, x
|
zan
|