- 在线时间
- 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.数论算法 " G$ ~" b8 b: h3 n
求两数的最大公约数 0 i; j; J# e& n! ^: V
function gcd(a,b:integer):integer; : u* @4 K7 n; L, Z0 E) `
begin
; c9 V% e0 @; Nif b=0 then gcd:=a
' M4 [: p3 ?/ Z* r3 F: L/ m. Eelse gcd:=gcd (b,a mod b);
/ w% T( C" H. ]) s: Q0 _1 R6 H L0 B- Gend ; 6 a7 @; X" R# {$ P, `" o. }
. D4 J& S, o/ u$ D% K$ V6 V求两数的最小公倍数 6 r8 R( y) n4 S! t* j- Q& H
function lcm(a,b:integer):integer; ! D3 D$ P; N, w& |3 M9 E
begin
4 }1 a- P& N) ^) [, n& Oif a< b then swap(a,b);
9 s. D* W7 \ ]4 ilcm:=a;
, V2 Y8 h- b! ?while lcm mod b >0 do inc(lcm,a);
2 e0 _ ]5 L2 t9 F* d9 e# N' pend;
* P; A, \ c4 ]6 t3 ^7 @1 }8 q P* T S3 m
素数的求法
- Y7 t, F9 _# A" VA.小范围内判断一个数是否为质数:
( R/ D4 P/ g4 y! |) Dfunction prime (n: integer): Boolean; ) y/ I4 \! u3 w
var I: integer;
3 i3 L* i; E4 V+ W7 Pbegin ( Z( ` e) z# r+ Y, \ m* x+ J
for I:=2 to trunc(sqrt(n)) do
# q( r- b, w" H6 j* iif n mod I=0 then 7 x5 H y/ d: I1 K" _: o& i* N, Y5 [
begin 2 n6 p1 i6 U% Y2 s7 V1 m7 ~) F
prime:=false; exit; + t: X6 {: P7 e! a. l0 T9 ?$ @
end;
' k% {7 r& k# @! z4 Aprime:=true;
; d8 x8 y; i$ }4 n5 c- jend; : z' ~- V* Q! C8 N; E4 E5 e/ C
K8 m; k# }- w8 g, Q; ]B.判断longint范围内的数是否为素数(包含求50000以内的素数表): & l& v3 Y1 E5 P! ~, g% ?
procedure getprime; ( m7 j+ T4 }: m9 J7 h
var
. S; m9 ?0 ^2 ti,j:longint;
5 S$ u7 q6 M( X4 l4 Up:array[1..50000] of boolean; 6 k+ {+ z) t2 F+ m8 b
begin
% E" ~, l( B. Q: h {% N4 Vfillchar(p,sizeof(p),true);
& z- X; d! }/ V* Gp[1]:=false; 7 N5 j$ k5 R4 v; k- v. f% ?
i:=2; $ s' R- z+ R3 L& e/ H
while i< 50000 do
# f5 Y# H6 _3 \8 X5 }: j) G8 Dbegin 7 O' H: H: C# G
if p then
( z. M- v/ V E# K4 Ubegin 2 Z# U* X6 @' d6 Z8 z, N" N4 T
j:=i*2; 5 J0 Q; W& A+ X3 N: z* u* H1 {
while j< 50000 do
8 S% W; y. P( X* E1 ]begin ; ^& r5 ^1 ?* n% j% x! i
p[j]:=false;
3 ~* j0 p& O. g) @inc(j,i); . t! V V, [1 j1 k9 R) s/ d: B6 L
end;
& |/ F. C6 p# v) \6 l4 B: q: m/ E! @end;
6 S% J, A8 A. G) F6 L. Jinc(i); $ B/ F! A' B' w \+ ~4 u9 k
end;
. v9 G4 w k- ~1 x, c- a& v8 ]: kl:=0; 9 @8 l0 t( ]7 u; a- f
for i:=1 to 50000 do
! y7 E/ n1 E- G& M; \" R4 eif p then . D, `3 T( L& K# W1 D( u2 d
begin * V* J! O8 N% b. j( d/ F1 B0 o1 [
inc(l);
5 ^3 T, J" \; `2 r- Tpr[l]:=i; ( ^* a* C1 _! D* q6 E2 h
end; 4 y( @- v" B* o. S& c
end;{getprime}
5 b% K% d. w0 V5 z( p7 bfunction prime(x:longint):integer; ) {$ j X2 G' L% Z7 }- p
var i:integer; ! k! m0 H4 F, ^: J
begin
% V8 t3 G. H5 X* k+ Yprime:=false;
# [. _+ {1 C6 r2 S2 gfor i:=1 to l do
1 ~; m. G: e7 F7 {( K, |% J# h+ sif pr >=x then break 7 E3 b- L2 u4 w" N. [
else if x mod pr=0 then exit; ! i ^0 C9 K! `1 k4 P4 Q( l
prime:=true; # l0 h, Q1 {/ u& {% f! X
end;{prime}
2 L: O1 b5 L. T# ?( _9 |& V4 D1 d; X/ T+ A4 }9 }* n
2.
6 ^6 S! T* \$ d( ~& m
3 p; `; x! T3 Q9 N3 T3 {3. ) z8 p, u/ K) e8 u: i
0 \; L7 H& X+ _1 {4 d4.求最小生成树
( S% @9 d0 x V2 [& B% nA.Prim算法: $ l' x+ s) w- Q- `0 J" y( m8 r
procedure prim(v0:integer);
5 Q1 F( {- t- R' M( t7 e( {2 p9 zvar
$ `" a& V5 w/ P% y! C& T9 Jlowcost,closest:array[1..maxn] of integer; * I0 g6 K6 T7 U! r* y; n
i,j,k,min:integer; / d, m0 d K6 `
begin
( k w y$ x9 Kfor i:=1 to n do
4 O( y$ n9 n h, }0 ]begin ! y3 t g- n* V3 J
lowcost:=cost[v0,i];
& ` Z- d) k- dclosest:=v0;
( ^4 d6 R2 I2 w8 @end; 9 h) i; _. _( T, B; Y& v
for i:=1 to n-1 do
) _6 L6 o& D2 U+ nbegin
* c2 c, D t/ H! G{寻找离生成树最近的未加入顶点k}
, d3 z/ T$ s+ @min:=maxlongint;
; k5 n/ j. L- u0 d6 }1 w3 @: Dfor j:=1 to n do 5 N! F" d0 ]7 i, m3 C/ g) [
if (lowcost[j]< min) and (lowcost[j]< >0) then
6 k% u' a& Y# P O# Q! I4 gbegin
% w& ~* W3 r% B% Z+ z* Z Rmin:=lowcost[j]; ; d, [' ?/ I4 h- v% Y/ j
k:=j; ' v+ c/ T4 f- u. h5 E" K( z' h
end;
3 {+ v. [$ `# B6 `2 R wlowcost[k]:=0; {将顶点k加入生成树}
$ `% \& L3 L4 G) V. f8 Z* x( J$ J{生成树中增加一条新的边k到closest[k]} ( T1 a" q, s# z1 ^
{修正各点的lowcost和closest值} 8 _ }- p! }9 w
for j:=1 to n do
% ?! y7 l2 k' p5 E0 B7 M/ l3 oif cost[k,j]< lwocost[j] then ( C1 S) N1 ~3 ]6 ?; C( s1 u0 h' R
begin 8 V/ _, K/ q$ u3 j" Q
lowcost[j]:=cost[k,j]; 1 M7 c* Y$ d" T8 k4 n! x$ l# Z+ w
closest[j]:=k;
/ Z' L: Q+ Q, G$ H8 P7 R: aend;
8 g; r" O3 u. H6 F8 R3 G% B) w7 {end; 5 ?. T J' J9 o/ @
end;{prim} 9 z2 ] f: |6 R! ^
B.Kruskal算法:(贪心) 0 `) d; {; i9 h* f
按权值递增顺序删去图中的边,若不形成回路则将此边加入最小生成树。 - D4 U. Y4 C) Y7 ?1 o1 ~1 B
function find(v:integer):integer; {返回顶点v所在的集合}
8 [% u' m/ V1 T. Vvar i:integer;
0 n" i+ `7 l/ Z! a' _begin ) V7 E: d& {4 v. j0 f
i:=1; 0 W; m5 V0 L- Y
while (i< =n) and (not v in vset) do inc(i);
* U; @9 x) V* x, t- r0 _if i< =n then find:=i 8 \8 @" s4 h$ d, J: @' n
else find:=0;
- v% ^- e3 z* m! J+ uend; . n7 P9 D( D D
procedure kruskal; 9 p+ H' @# R7 S& o3 U9 P
var 4 q, [- Y4 x% u
tot,i,j:integer; 5 G* x% w; Y2 i) o3 M R- e7 X; ]
begin
0 p9 q, k+ M/ H5 X% `: ufor i:=1 to n do vset:=;{初始化定义n个集合,第I个集合包含一个元素I} ) ~+ D8 Y2 C9 u, \
p:=n-1; q:=1; tot:=0; {p为尚待加入的边数,q为边集指针} & v8 i1 `9 I7 f- v
sort;
; l P9 `3 U6 U, ^! g{对所有边按权值递增排序,存于e[I]中,e[I].v1与e[I].v2为边I所连接的两个顶点的序号,e[I].len为第I条边的长度} ( j( ^, c p; z9 M: k N! V6 X
while p >0 do % G- c( B; S0 @- T3 v' L
begin
1 T% U5 H% f, A r8 o Xi:=find(e[q].v1);j:=find(e[q].v2);
8 ]- v7 S& r% K* d x6 z. ~5 \if i< >j then
) _1 I3 Z$ h4 j" Kbegin + p: P5 Y" ~2 _. I$ @% d: A, Y
inc(tot,e[q].len); ! b" z8 {! o$ i9 p% l: C
vset:=vset+vset[j];vset[j]:=[]; 7 Q7 n" _$ v* [" R9 n' Z( P6 i7 N
dec(p);
* a8 T F) d) C$ iend; ' B6 h( F: G2 E* D5 a+ q: v) M9 F
inc(q);
% l2 E/ f' x4 n2 oend; 4 i6 p q' [2 P; ?, X
writeln(tot); 8 V5 B0 Q8 m* e# u7 H
end; : Z0 [/ Q) d! n( U
6 {7 R6 R8 Q1 f/ O5.最短路径
8 M. B1 z/ Z8 |A.标号法求解单源点最短路径: 2 Z9 D+ E- g) M' c2 U! {
var 2 V5 X) ?. s/ e4 G* E
a:array[1..maxn,1..maxn] of integer;
7 n5 t3 B+ u: v nb:array[1..maxn] of integer; {b指顶点i到源点的最短路径} 9 S9 I$ c+ S' @ P3 b- B% }4 I, Y
mark:array[1..maxn] of boolean;
$ g# r# R1 v* I* @+ R. R4 h: S" F1 ^1 o
procedure bhf; / o9 D" B$ _& H3 W; q7 N
var $ |0 M- x+ @# X: ?2 P/ E+ ^2 j
best,best_j:integer;
4 M) p( o- D# U/ ebegin
; d _. z; [0 c' R( H [fillchar(mark,sizeof(mark),false); ) P$ ~1 p- n. S& ?2 V9 V
mark[1]:=true; b[1]:=0;{1为源点} & J) [% v+ Z% @7 @0 s3 X+ R% i
repeat " F$ H) K6 e0 l; @5 a
best:=0; 7 t8 D8 z6 }3 O! F" F
for i:=1 to n do * {# V2 h q0 k+ t$ a
If mark then {对每一个已计算出最短路径的点} . ?% ~" W4 G1 r8 T& ?
for j:=1 to n do
+ V2 \/ _" O+ B+ Z kif (not mark[j]) and (a[i,j] >0) then * a d% R6 l: G9 |# G
if (best=0) or (b+a[i,j]< best) then / B6 p: y1 K9 p) ^( m/ \
begin
' U) ]/ I( o5 ~best:=b+a[i,j]; best_j:=j; - a* v+ R. z7 u M& f8 M& U
end; % ^; ]2 D2 G0 I4 v
if best >0 then 2 O) o2 m2 B2 t _; I, E
begin 5 `* R1 c: w) p! x
b[best_j]:=best;mark[best_j]:=true;
5 G, H! D; m" Z2 P% q" J7 r Rend; 8 N; N! \& |) i& I
until best=0;
6 d$ {5 D8 ]9 l9 y6 G" F# \end;{bhf}
7 k. f! n1 W+ u4 n$ [- S8 r" @/ Y0 K- b* a
B.Floyed算法求解所有顶点对之间的最短路径:
6 h) q, P* g ~0 v$ ]. tprocedure floyed;
7 B, d$ @) X( I1 m1 n6 W" Ibegin
& T- e& L: {" z/ A( Z" e4 D1 T; T6 G% [& ?for I:=1 to n do
, d9 c" S! f# f, Ufor j:=1 to n do
4 o, ~3 X# t2 ~: ~2 n$ qif a[I,j] >0 then p[I,j]:=I else p[I,j]:=0;
9 R' w1 e4 o6 j+ t# t{p[I,j]表示I到j的最短路径上j的前驱结点} 2 e0 s- ^5 J0 l
for k:=1 to n do {枚举中间结点} + k# F m* A8 I3 p) C$ ^
for i:=1 to n do ; m9 f$ M# @3 U5 w: x; v4 |
for j:=1 to n do : j: ]" [9 p; k L' {
if a[i,k]+a[j,k]< a[i,j] then
3 b1 {) g/ g. a! W7 t) Vbegin 0 d: D; T- L: u- \
a[i,j]:=a[i,k]+a[k,j];
$ D7 D% S- {- d* K) np[I,j]:=p[k,j]; . w7 b! G Q4 }$ R" E4 L
end;
' E0 a; Q; M# B! p I. ?- {end; + x1 K) S4 i' K4 ]2 ] p! B
C. Dijkstra 算法: 8 H# o% P9 q, Y: b: x4 R
类似标号法,本质为贪心算法。 * K" k3 {$ q8 q
var . m/ [, ]7 ?) }/ t2 I f! h W
a:array[1..maxn,1..maxn] of integer;
- Z; s3 e/ f/ \: b8 gb,pre:array[1..maxn] of integer; {pre指最短路径上I的前驱结点}
. a9 S: w7 B) u$ n2 Q* hmark:array[1..maxn] of boolean; 2 f, C5 `/ U4 ]! Z
procedure dijkstra(v0:integer);
/ T+ y' D0 F2 T, J3 q) pbegin
2 [) [: P: P+ ?4 m. Ffillchar(mark,sizeof(mark),false);
9 m- b- A: j' qfor i:=1 to n do
+ C* Y% w( s9 Nbegin % J; P8 g7 u c
d:=a[v0,i];
$ N+ p& d) T0 f4 Dif d< >0 then pre:=v0 else pre:=0; 0 o0 [) s7 D2 ]5 V
end; 3 m5 S* j2 q" O q+ ]- Q
mark[v0]:=true;
! a7 _) F' ^# Y! ?; x4 e! J% Erepeat {每循环一次加入一个离1集合最近的结点并调整其他结点的参数}
, g, q/ ~6 D% L& {min:=maxint; u:=0; {u记录离1集合最近的结点}
g. B& b& S) Pfor i:=1 to n do - W" n2 Y! }9 }0 f1 @& U
if (not mark) and (d< min) then
5 o2 Q/ V! ^$ @begin 5 U! e% r5 \! o4 D( s ~& w
u:=i; min:=d; 4 S( U7 U- @% t1 J' F/ G
end; % A5 E9 A5 T! B" U0 |
if u< >0 then * z5 C& k9 t- l$ A8 Z0 v7 Y
begin
/ m! G) P1 n0 f$ e5 m8 Rmark:=true; / h, \9 G% t! E. `$ ?: A
for i:=1 to n do . s/ Z3 ]6 [- X: H2 m
if (not mark) and (a[u,i]+d< d) then * F* L- y" r# p6 |4 T3 h
begin
$ o4 B$ Z8 U. Z6 k: j o! td:=a[u,i]+d; * P& r. l, Q Z4 H- S
pre:=u; ( L, {) n x8 f5 O$ }8 e
end;
3 _: V. o: c, vend;
; `( Q! B+ [ l/ J1 vuntil u=0;
" I/ U r; V# aend; % v, X) W8 `: J/ ]- o0 Y- e
D.计算图的传递闭包 2 v. q+ z3 M l& S* o( P$ u
Procedure Longlink; ' }# L t, b2 T D4 R7 `
Var ! F& z8 P/ ~* r& t( T k
T:array[1..maxn,1..maxn] of boolean; 6 K! M, p" @* Q( ?* v+ x
Begin 4 l7 Y# W3 b3 H! A
Fillchar(t,sizeof(t),false); 4 T: N' }, Q( Q1 |
For k:=1 to n do - }; M& f( `3 v6 A+ P2 [0 b
For I:=1 to n do & B3 Z. T/ p! p! a( \
For j:=1 to n do 1 O K; ~6 t7 e4 f' t
T[I,j]:=t[I,j] or (t[I,k] and t[k,j]);
" E2 t8 L# z* v! h! q5 P; QEnd;" }9 u9 _2 {# [; j, @# {
& X+ V* ] S X! T1 ]
|
zan
|