- 在线时间
- 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.数论算法
5 ?2 G9 y# M+ U求两数的最大公约数
2 g4 A8 N7 ~% }* N/ x" ?function gcd(a,b:integer):integer; " W% w8 g6 V- H
begin
( n; }' ]6 v6 }) w( N ~" m2 sif b=0 then gcd:=a # f' Y/ ]! F- \) E1 p9 y% o5 h
else gcd:=gcd (b,a mod b);
; W. Z3 g* g2 y; cend ;
% v; ~' f' Y1 s! g9 Y1 x/ p7 A: W, j7 ?% M5 _* [
求两数的最小公倍数
3 p( E6 ~% A0 I4 e; C9 L0 G# P6 Xfunction lcm(a,b:integer):integer; # Q" d% [8 c5 C3 v' G- l( J( w8 n
begin 7 Z- \# [$ f1 ^9 l, x. p% [
if a< b then swap(a,b);
0 S0 r. f5 I4 C: m+ x" l8 Vlcm:=a;
1 u& C! O1 {4 N& F" L! F' Ywhile lcm mod b >0 do inc(lcm,a);
3 o3 Y3 l, K$ s& O8 N1 Fend;
) @; Z" i# ~ s" H9 w1 o* n1 r
+ e' I) z( P# Q& {2 I0 k2 m素数的求法
% m9 l+ ^3 c2 l5 l: D6 i+ CA.小范围内判断一个数是否为质数: $ G. R) K7 _+ q, P
function prime (n: integer): Boolean; ) D% @1 D" H- E' a
var I: integer; 5 K9 y0 v8 K$ |/ {2 Z- l% Z4 t
begin
, H3 K q/ V Xfor I:=2 to trunc(sqrt(n)) do
) Y1 D; Z: r' p6 ?% _8 T1 b' C2 sif n mod I=0 then
9 g& i) S7 y$ ~' lbegin
' O. h7 ?. J! x! B lprime:=false; exit; K- _: r: ]( P+ k! R
end;
3 Z) ~6 S2 g F# u7 Vprime:=true; | ^3 H2 i5 W% L
end;
t! A1 ^ N6 x6 _( T9 c+ N* |; h
' u, Z' J% J" e3 Y5 a7 N- BB.判断longint范围内的数是否为素数(包含求50000以内的素数表): $ V; F2 p. p! \+ T& f9 |
procedure getprime;
! t6 J4 q4 r9 g4 q) P* Jvar
/ L: ~, h7 B( }! C3 c7 ji,j:longint; & b* m+ ~' g& U) t4 a' W
p:array[1..50000] of boolean;
6 V+ b+ l- u1 \- W# hbegin / w% @8 n2 E7 B7 j9 E% m/ t$ g* ^
fillchar(p,sizeof(p),true); . D( U5 A" X: x5 | x0 n6 A
p[1]:=false;
5 [- r0 h" Z' B, u8 ii:=2;
/ w4 o% l) U8 b' l$ f0 twhile i< 50000 do 0 @/ ^* |4 T' {9 Q1 \
begin / {/ k! t+ Z7 K" }& S: i
if p then : \+ z3 q1 i* w% B. G, n2 d
begin
2 g* O* E" E6 K% K, o6 a7 L' N- {4 ij:=i*2;
9 b/ E+ ]$ `: J! Q( x5 T% B, Wwhile j< 50000 do $ {& W) B3 E5 t2 H: W& q5 Q
begin
( [, C: u6 t) p Tp[j]:=false; ( T! x& R \: A+ [3 ]
inc(j,i);
6 x n. p8 B1 T; T( Jend; 0 v+ G6 z4 L; i0 y! F6 g8 R2 G" c
end; , M7 j( A& z% y8 |6 g
inc(i); / p9 ?2 t4 O8 ~- k& T
end;
2 i! {) h% e% c) Vl:=0;
' J7 s* X1 s+ g" V; \6 xfor i:=1 to 50000 do
# Q% X* \5 `% uif p then 8 w6 b# x4 C& F4 Q- E, x6 |
begin % W+ x1 c7 h8 b8 |7 I/ a' Z9 }, s. O
inc(l);, R, \- T5 S3 M0 h M- |( S% ~
pr[l]:=i; % t6 H: `3 U2 U) }' M. L7 p1 _, W
end;
) a0 @0 b% j$ `end;{getprime}
8 k. a s5 M, Tfunction prime(x:longint):integer; 4 L4 E) u( }7 J
var i:integer; ! i4 y8 n0 A: m- _* t4 f( w
begin
, \) t4 z& P- T0 o& e4 d1 lprime:=false; & p3 S0 z4 ~. o& B' I9 N! D* o5 f
for i:=1 to l do 4 y( n J% w( Y1 A; f* s6 ~
if pr >=x then break - T; j- p5 @' u
else if x mod pr=0 then exit; 4 [! J0 `# ^0 I# U$ r% p# F3 M8 u1 F
prime:=true; # T% K+ k/ N; Q1 D! s/ N! w9 y
end;{prime}
+ [! e" k7 R B3 s* w' U; k( ~: D! d2 x D: b1 W
2. 6 W% z& G& J6 y0 u1 ~% ?+ h {3 P
) V% B# g/ \8 d9 ]3. * W, j* L: I: c( a0 B! \% ~
8 S3 _0 w! r, z1 X
4.求最小生成树
) N' h7 g4 }4 g& U2 H2 QA.Prim算法:
. V- q7 Z) a4 o9 hprocedure prim(v0:integer); 6 F/ R z" e* Q# R0 z5 G
var # G, j9 v) F, _, Q# @' |/ ]3 l
lowcost,closest:array[1..maxn] of integer; 0 S6 W: o& o5 r: H2 y) m) x
i,j,k,min:integer;
H; E# E2 D3 P) f3 ?$ I/ H' [begin . \% ]" |& g# t5 p
for i:=1 to n do 4 y0 p/ q) ]: G
begin
8 O! }3 i! y+ t# F% {# [lowcost:=cost[v0,i]; , S0 R' ^! }; F0 u1 r2 @
closest:=v0;
# u, t# [, f- t# B$ s) [end;
6 Y- t0 j! b) }9 N+ d* J9 T3 G! \for i:=1 to n-1 do * B' D7 p. C" u' T# z: l
begin
$ ^6 C4 K0 H+ J- b{寻找离生成树最近的未加入顶点k} 7 p3 b5 ?0 R& x
min:=maxlongint;
' q. C7 H. a3 pfor j:=1 to n do . m7 M% U7 ~3 c% ~# [; ^7 k9 Z" t$ j
if (lowcost[j]< min) and (lowcost[j]< >0) then , F2 @; f" A! g' M
begin 7 D4 Y' z# [/ q" h% w2 F
min:=lowcost[j];
4 {; @0 g( Q4 E" y* }2 ek:=j; : e4 }# U& F! C5 r
end;
- m9 z; F5 M: R: _& {lowcost[k]:=0; {将顶点k加入生成树}
9 {/ T8 P8 A: y+ N/ C5 A1 z2 D{生成树中增加一条新的边k到closest[k]}
9 A1 N( A6 v# J+ b# J! J( ?{修正各点的lowcost和closest值} 1 k F, v( ] v$ Q: U$ H, z0 D4 P' @
for j:=1 to n do 6 d6 _1 n' ]$ Y+ N' D+ t. ?
if cost[k,j]< lwocost[j] then
3 k# i+ p( e1 c5 O% }- pbegin 4 T- n3 L3 l3 ~8 I! @
lowcost[j]:=cost[k,j]; $ \8 s+ t/ f6 L$ u, V& d) M
closest[j]:=k; . j8 I E5 e5 Y5 s
end;
- c9 A; ]0 Q2 w0 Oend;
& l/ U5 W) G5 u( B1 |end;{prim} & V2 I, q& r! |
B.Kruskal算法:(贪心) " \ m4 H' g; N1 |
按权值递增顺序删去图中的边,若不形成回路则将此边加入最小生成树。 " l7 I; J1 E7 R8 p1 c0 ?1 N
function find(v:integer):integer; {返回顶点v所在的集合}
5 W* c- t: R9 L' j% E& S( tvar i:integer;
1 Z0 f* c o, Y5 ]3 Sbegin + ~, b" C- Y5 ^1 Z
i:=1; ; o0 u% {( r& ~3 A: v6 v
while (i< =n) and (not v in vset) do inc(i); # F3 u- E* r+ L% D/ o
if i< =n then find:=i
+ |: d* `) F9 Z; b' D0 zelse find:=0; ; J% [+ F7 D3 J. K$ w5 p
end; & j# s. I9 n& y8 V* h# ]
procedure kruskal; 8 h. S% j5 G/ \8 X2 ]* J$ M
var
; n) e# ^$ W5 G0 x9 _% h' G$ _tot,i,j:integer; 1 |% Q/ j! b6 Q7 L4 b ]
begin 4 Y6 i! t2 D- b6 ]/ y
for i:=1 to n do vset:=;{初始化定义n个集合,第I个集合包含一个元素I} : C+ t6 f4 @6 x! M
p:=n-1; q:=1; tot:=0; {p为尚待加入的边数,q为边集指针}
! q* R# _2 a) q+ N Nsort;
( p5 b( {# j |& y- ^{对所有边按权值递增排序,存于e[I]中,e[I].v1与e[I].v2为边I所连接的两个顶点的序号,e[I].len为第I条边的长度} 8 }3 l: E* E6 Y& C- `1 k
while p >0 do
7 X3 u' M% G% z* U- Wbegin
, k, a& d6 n7 U; G8 e% V3 z ti:=find(e[q].v1);j:=find(e[q].v2);
- z9 o7 J @! z3 `2 ?+ q- Xif i< >j then ( N$ d1 w4 L* s/ ]. ~& `9 O
begin 9 C: m3 b1 f# h
inc(tot,e[q].len); ! S- Q( Y- m' a- Q# \* R- }2 l
vset:=vset+vset[j];vset[j]:=[];
! h- u0 k1 G% L. y- L ^3 t- ~dec(p);
$ N' J) o0 x. H2 ^6 }; D) A9 G" qend; 3 p- m. x" i- f# |& t& \/ X3 c
inc(q); , I, e P- F0 K) T
end; R% @3 h$ ]/ b b' K9 n! r
writeln(tot); 5 }* z/ b" |2 H+ Z0 K5 z$ i
end; $ Z& e/ `* e2 J' J c; p F
2 z7 J. \1 V, Y4 B+ X5.最短路径
$ e3 w+ z% t1 H7 xA.标号法求解单源点最短路径:
& u6 `4 {! \3 evar
4 o! A# _/ L& S# Ba:array[1..maxn,1..maxn] of integer; 2 [1 y4 v1 l q$ O1 d& w7 A6 w" u
b:array[1..maxn] of integer; {b指顶点i到源点的最短路径}
$ b. o" S# F: }1 {" {' nmark:array[1..maxn] of boolean;
& y6 B2 k5 p" U( ?# n% S7 n0 Q Q) Y* G. ]4 {+ ^* F
procedure bhf;
) G/ w7 T! F. Y/ Wvar " Z; M* U3 I: Q4 G0 y* u
best,best_j:integer;
: W: J% `# a% S$ R8 ~begin 7 X, g$ H! H- e. l# k* J
fillchar(mark,sizeof(mark),false); . | w6 ~% o6 I1 J; w0 y: L8 G
mark[1]:=true; b[1]:=0;{1为源点} ' n3 h- P6 M7 s: ?2 O
repeat 4 ^( p& ^8 k3 v) l3 O# P
best:=0;
& `6 z1 t5 O- F: |+ Xfor i:=1 to n do : w8 G" @) a5 _/ o* v: ?+ f
If mark then {对每一个已计算出最短路径的点} ) d& Z3 B% Y4 D* U- O
for j:=1 to n do
# K6 J1 l$ ]+ _& _1 Kif (not mark[j]) and (a[i,j] >0) then
0 p3 Z& @- z- C& ?# u& E, U# g" Aif (best=0) or (b+a[i,j]< best) then
' V# |2 y6 t8 t9 \( @" E* \begin
/ f) F1 u; S2 V% O* Kbest:=b+a[i,j]; best_j:=j;
) p" n% E5 z/ Oend; # w8 ~6 c# _- }) T6 Y, v, u
if best >0 then
! G- v! G+ s: F+ D( B& }! Kbegin 4 B5 f: {+ ?. e! I- I/ O0 M
b[best_j]:=best;mark[best_j]:=true;
2 W0 ^0 c5 `7 g" X' k% s& mend;
! @/ K$ x K" buntil best=0; 8 Z u7 [1 [$ t0 P$ J R& w
end;{bhf}
, Q2 R+ K1 j+ `! n7 r L5 w- i, w7 }& n% g E. \# K9 o
B.Floyed算法求解所有顶点对之间的最短路径: * G3 |* A7 o" c* ^6 E
procedure floyed;
G! m4 G4 d5 F: E L! f' lbegin # z7 Q9 ]2 ~3 r$ a+ x4 A
for I:=1 to n do ; x% {; X1 B1 H; H [
for j:=1 to n do 6 c' y4 G3 N9 J( ?
if a[I,j] >0 then p[I,j]:=I else p[I,j]:=0; $ U6 {* w" z" U/ t) S2 p
{p[I,j]表示I到j的最短路径上j的前驱结点}
5 m0 u7 ~. r! M8 Q- i, L: Xfor k:=1 to n do {枚举中间结点} $ p' f1 V- m, D+ J/ m: K/ O- x4 R
for i:=1 to n do 1 _, S: W4 O/ k7 O1 L
for j:=1 to n do
+ L: H: n0 z r7 i/ ^% yif a[i,k]+a[j,k]< a[i,j] then
7 o) V9 \" a9 N" sbegin
/ ^% [6 s1 H, Y | s+ D/ fa[i,j]:=a[i,k]+a[k,j]; 4 b8 z5 V+ k7 {% y9 A
p[I,j]:=p[k,j]; % `1 Y5 q" d! c9 s
end; + R8 l0 U# {& N" @5 h1 I
end; 8 F5 x! L. j, {, i% {. O" N1 W
C. Dijkstra 算法:
+ W+ Z0 x. K8 ?! k# ^类似标号法,本质为贪心算法。 5 E$ a! A$ k/ q# @; b) f
var
' {; W! ]6 O; I5 ?" oa:array[1..maxn,1..maxn] of integer; % U! @ X, x" q$ [
b,pre:array[1..maxn] of integer; {pre指最短路径上I的前驱结点} + m4 i8 y" f% l- A: f& T; j( {
mark:array[1..maxn] of boolean;
1 S+ g( V3 l* T) K6 @. e3 X. lprocedure dijkstra(v0:integer);
4 a" ]" w2 p5 B7 S; T2 Kbegin 4 ~0 T* a# n! F( {) ]8 f. @, g
fillchar(mark,sizeof(mark),false); ! }- P& e8 S& ]5 H5 w2 Z: k
for i:=1 to n do 2 O# m) o% Y4 B7 L, _. D# r
begin
% V: s) }. @4 ]3 `d:=a[v0,i];
* L. Y! [! e7 L# c2 V; gif d< >0 then pre:=v0 else pre:=0;
, H% I1 v- `" j7 V( qend; 1 P9 ]) W8 d' D* [
mark[v0]:=true; 7 J5 [3 [& G4 W9 T
repeat {每循环一次加入一个离1集合最近的结点并调整其他结点的参数} 4 D1 {" B+ ^2 R: H$ X
min:=maxint; u:=0; {u记录离1集合最近的结点}
1 z- Z- U* S0 xfor i:=1 to n do
9 b: }$ c0 o* k; P5 D; Fif (not mark) and (d< min) then
6 X, X( K% R% D/ E7 u8 n4 Ybegin
7 F# f; u3 S0 Y8 ?+ fu:=i; min:=d;
9 H1 [; N, [8 s0 r% I9 Fend;
8 Z$ N. z9 Q7 X6 Mif u< >0 then
6 _1 T6 {4 O4 G9 t1 ?" U9 {6 h/ A$ x! xbegin 4 Z3 R+ w+ W7 j4 ]0 S4 I" C4 N O4 K) P
mark:=true; " o- e- U4 [, U' p- Q
for i:=1 to n do ' G6 q2 J9 p- a: w0 ?- P. y
if (not mark) and (a[u,i]+d< d) then 4 X/ `2 s7 C5 L6 D( k/ S( L
begin
4 {3 d0 j7 A" ]7 ?" o9 h) kd:=a[u,i]+d;
' O ~, n- T- j+ R7 p' [! Z+ jpre:=u; 7 h/ s( ]. V! ?/ O! Z- m
end;
: E7 G4 M) I- G& \. Fend; t$ c, C4 ~) ?7 a
until u=0; 7 M5 q. }1 K: c( S2 y
end; , E( k( |8 M ?/ B- s0 M* {
D.计算图的传递闭包 " _2 u. }" r1 b/ w
Procedure Longlink;
7 n" O. K& }1 {& ~# j3 b0 SVar ! P1 {$ A& [6 b1 y
T:array[1..maxn,1..maxn] of boolean;
2 f# C8 u' x' G+ e6 vBegin
3 @" P: I) w* ]1 s) D$ P3 DFillchar(t,sizeof(t),false); 9 E+ I- G: u5 j, c
For k:=1 to n do
4 y1 O1 w O& yFor I:=1 to n do % U! S' `* k0 H0 L; {- A
For j:=1 to n do
1 x6 e9 D7 u, z( k9 U; j! c/ sT[I,j]:=t[I,j] or (t[I,k] and t[k,j]); $ `, D E1 g- c5 F) o; v1 X
End;
. q: Y+ [5 h+ o3 p+ G; \" Z) z, m; h
|
zan
|