- 在线时间
- 1029 小时
- 最后登录
- 2017-4-30
- 注册时间
- 2014-1-21
- 听众数
- 213
- 收听数
- 2
- 能力
- 100 分
- 体力
- 15807 点
- 威望
- 98 点
- 阅读权限
- 150
- 积分
- 8571
- 相册
- 0
- 日志
- 0
- 记录
- 3
- 帖子
- 1549
- 主题
- 715
- 精华
- 2
- 分享
- 0
- 好友
- 542
TA的每日心情 | 开心 2017-4-28 17:18 |
|---|
签到天数: 415 天 [LV.9]以坛为家II
 群组: 乐考无忧考研公益讲座 群组: 2017美赛两天强训 群组: 模友会交流视频 群组: 群组: 国赛讨论 |
1.数论算法 ' t+ M# i( P* [( b( w: r
求两数的最大公约数 ) D+ w# N+ z9 _# c+ G
function gcd(a,b:integer):integer; 5 ^* c& F% M" H7 J4 a5 W5 J
begin $ V( s7 e5 R7 n- F
if b=0 then gcd:=a
# H% M2 ^* }/ J& ^6 Y: R' delse gcd:=gcd (b,a mod b);
+ t8 A, F+ Z1 ~! k. i( [% }end ;
& M5 u1 U+ m' J) R) g3 I' A& m; b, q7 L5 C& P8 K8 Z' l
求两数的最小公倍数
7 I+ D6 Y8 r, ?, Yfunction lcm(a,b:integer):integer;
& [, y9 m7 H1 ~# g6 tbegin 6 {" k4 @8 i6 n- o" B3 \4 d) i
if a< b then swap(a,b); + H/ r2 h6 e8 ?0 l* H( @9 d
lcm:=a; ' @/ p# @4 r- M+ A
while lcm mod b >0 do inc(lcm,a); 1 T1 |5 f7 W' ?9 w/ i. t
end;
6 R, Z6 F% p' d' R" n" s, S
x/ ~3 |9 D- j" t- J- ?4 [: M7 }+ E素数的求法 6 c$ W# H( ?, o) q2 m0 a T
A.小范围内判断一个数是否为质数: 6 T4 D$ o0 k1 I; g
function prime (n: integer): Boolean;
0 C2 [8 z* g5 qvar I: integer; " e+ X9 I; n, W U: d
begin 2 \8 F7 y c0 C9 j7 j
for I:=2 to trunc(sqrt(n)) do
# g- a6 W) ?% c& U+ Wif n mod I=0 then ; w0 F7 H+ X; f0 D. t
begin
2 [# [; _9 L. @# ^- L) n& }prime:=false; exit; - V0 j# G: Y0 f. j( J
end; 2 ]2 w# r" A; L
prime:=true;
: d. j# d) N1 \& m3 b" j, X% nend; U( |7 M( ]$ A3 v) H* I$ x6 S
' Y$ ^* b' ?4 }; M) kB.判断longint范围内的数是否为素数(包含求50000以内的素数表): ) A0 t6 h9 G% h8 o5 Y$ ^
procedure getprime;
9 Q( n7 U' u' `, rvar
$ m' v, d6 V. \7 J$ Ni,j:longint; 2 c8 k& s1 d& @! ?, @7 W
p:array[1..50000] of boolean; * h/ J. q- o& x) q d! ~0 i
begin
, U3 r- d; f% r) D! Jfillchar(p,sizeof(p),true); 1 s; f, ?+ v- {
p[1]:=false;
5 l; B+ t6 ~: a( ^, xi:=2; 5 X3 c4 |+ U, ?# [) @
while i< 50000 do 3 }% V6 p( Z+ Z# L! u: a
begin
7 j3 r. J9 d3 h4 pif p then
; n4 H8 g3 q+ Ubegin # Q% m; c0 a4 Z6 m3 C" h
j:=i*2;
C/ k, O' [* C' { Hwhile j< 50000 do
, L0 W3 U% Y- F3 r; `1 u3 vbegin
+ ]1 F8 K# c1 C# a1 Q; }! {p[j]:=false;
+ x6 k: c# }. j: pinc(j,i);
9 I$ R q0 k1 D# @) n- r" f' f9 k/ Iend;
% i t) S( _" S* @7 _end; . a# V+ {' d0 h1 @' e
inc(i);
- c9 q7 S3 Z! \( b: @6 Hend; & W/ _# B$ K# i) j1 x6 m, W" K
l:=0; # w; P- C" ^9 F8 D2 l7 B5 k- A1 n
for i:=1 to 50000 do
1 E5 h# ^+ C- vif p then $ u3 {& {4 N/ r5 t5 r& a* q* D
begin
`1 C5 @) v% G& {( B4 e& kinc(l);0 F O% V% {( E( U9 m
pr[l]:=i;
- J3 J0 l' U( G6 L( I. Kend; 4 X) N. G5 c) H8 H+ ~9 K, w
end;{getprime}
. w% `6 h% |) l4 R7 N% O g5 |function prime(x:longint):integer;
) b% J8 F. h- ~4 R! ovar i:integer; $ x/ c' V4 L* F, j
begin
" G% _) _( o5 {# r4 R4 Q% V2 Gprime:=false;
3 @8 N5 L1 Z6 t( Qfor i:=1 to l do ) r; O$ b& a4 n
if pr >=x then break
% e+ \9 O0 i$ J7 ?* [& \else if x mod pr=0 then exit; + y! r) R/ H: `/ S
prime:=true; 8 _* a1 l& ~* e( @) e
end;{prime} * Y* {0 ?3 Y; q$ ?- V4 ]
* } o' M# u+ P* n
2.
3 Q+ b) a4 s: d( Z( n9 T) M) J) t( ?: U0 }: \$ \; i
3.
/ R3 j. l& w+ \3 H7 R0 ^/ o' Z( y1 e( l& |
4.求最小生成树 T9 a$ v, m+ \
A.Prim算法:
5 A) j; b# R' d( [# \/ i4 T* kprocedure prim(v0:integer);
8 J1 }2 w' N) r0 z7 Pvar 3 i$ i, h0 J8 R
lowcost,closest:array[1..maxn] of integer;
0 P) B/ z. |) T5 j( @; i, X/ ^i,j,k,min:integer; 2 q: `6 { m& h" n+ s
begin
7 T5 @0 ?8 c$ k( ? j& |5 qfor i:=1 to n do / o% d! N+ Z3 f# T
begin 5 h0 O" P! R0 _5 i3 C+ l3 J
lowcost:=cost[v0,i];
8 l: b3 @0 n9 n ~3 Dclosest:=v0;
0 {9 b& Y* p( F/ q8 O# [+ S+ eend; / ~- r. T: E, a
for i:=1 to n-1 do
- x, B' S- c, K" ?begin 8 n7 {+ K8 ~& z" ^& `4 f, I! A4 s
{寻找离生成树最近的未加入顶点k}
; n6 j' O4 I8 \1 g K3 @min:=maxlongint;
+ m( W2 j5 Z% e+ S* zfor j:=1 to n do ' s1 F9 G+ ?1 J! M9 h, l! r+ y. p
if (lowcost[j]< min) and (lowcost[j]< >0) then 8 j/ v/ r6 Y7 y
begin 7 H: v. a0 d( F0 ~4 R
min:=lowcost[j]; 2 v+ x W! }1 M" f" J4 C; j
k:=j; 9 K2 h; v* s% V( K' W
end;
' B! f6 Q* o' g' wlowcost[k]:=0; {将顶点k加入生成树}
- J. H. [( P9 P{生成树中增加一条新的边k到closest[k]} . v/ U* Z$ G+ D: i B! w, y; R
{修正各点的lowcost和closest值} - B/ S: C' L3 h. O. F' U7 n
for j:=1 to n do
. `* u: @3 X0 c- B. A) Zif cost[k,j]< lwocost[j] then
6 \7 J: [6 a3 e) p' J% ^/ P! N1 Bbegin
/ o) u5 F& D. x9 qlowcost[j]:=cost[k,j]; 9 J/ c. n) U" }8 [ ^# ?
closest[j]:=k; ( { l# G. r2 }+ \# ~' @9 P' e
end; 0 P' {6 B, D/ {8 B/ [
end; ) k8 a$ ^+ ^, d. }1 P( d& t
end;{prim} / h, M4 x) ~& `3 K% N- K4 U+ H, O
B.Kruskal算法:(贪心)
/ Z. e0 [5 f! Q! X+ S- g$ M% I4 A7 @& {$ F按权值递增顺序删去图中的边,若不形成回路则将此边加入最小生成树。 . c, g p9 E5 S
function find(v:integer):integer; {返回顶点v所在的集合} 2 {$ V8 j6 J. c
var i:integer;
7 D6 S/ s* Y3 |9 Vbegin ( y8 _: v9 l7 t/ Y( @5 B
i:=1;
5 |' J& `5 x5 x& Nwhile (i< =n) and (not v in vset) do inc(i); # e1 N/ d$ m! `; u9 k. I# z: l
if i< =n then find:=i 7 h& h, m$ G: |0 `* a Y
else find:=0; : i/ h1 c N2 P; b. k8 Q% W: ^
end;
9 l" d, P/ G) q; B0 b/ Z# j: sprocedure kruskal;
! t, G1 Y1 B% w- q* |var
+ ?( g T8 b5 B7 ^tot,i,j:integer; 3 @8 \; t3 l" H# V& k
begin 4 @& d- p+ _* U0 C* {8 e0 A
for i:=1 to n do vset:=;{初始化定义n个集合,第I个集合包含一个元素I}
6 l9 I) u# v. d( l7 h4 t9 op:=n-1; q:=1; tot:=0; {p为尚待加入的边数,q为边集指针}
- U+ h/ h0 T' J4 }' lsort; 0 D0 R* w. G# r2 Q" i+ d+ s7 t& F h
{对所有边按权值递增排序,存于e[I]中,e[I].v1与e[I].v2为边I所连接的两个顶点的序号,e[I].len为第I条边的长度}
5 d' U0 R% f8 b7 q* hwhile p >0 do 4 d; _6 s4 q' @# S5 h
begin , U! P2 q! c L8 V' L( p
i:=find(e[q].v1);j:=find(e[q].v2); - u) ?+ \% c( ~) M: A3 y
if i< >j then 8 }/ R3 l5 Z* n: y6 r5 I
begin
, I' L6 z* {8 Iinc(tot,e[q].len); . i% `7 \6 A/ c% {- ~
vset:=vset+vset[j];vset[j]:=[]; % `, E: E( T1 P4 ^
dec(p);
9 a2 k: i. K" L' D+ y; Dend; 5 ^$ m/ V. m$ h: o1 \& z
inc(q);
5 K+ c) S* B7 k4 t5 b: wend;
+ l! ]+ U2 m/ q( N6 ~writeln(tot);
8 ]& W' b& ]8 o8 q. C) }end; 1 Q6 \8 b4 a; H# Y- q- X# t+ {' F
! v: r1 q! T" G/ J
5.最短路径 7 i% W% A4 S- K& `
A.标号法求解单源点最短路径: 2 ^0 ]% M0 K' y& H0 |
var
" l4 b. W8 n, _# Wa:array[1..maxn,1..maxn] of integer; : H2 w6 C6 `1 i8 W) p
b:array[1..maxn] of integer; {b指顶点i到源点的最短路径} 3 |" `# \7 C2 q; f! G. P. i- S
mark:array[1..maxn] of boolean; + T# D! H" V* z. H: ?' J
/ r6 G3 k7 i: [7 P8 lprocedure bhf; $ K" J+ t5 a- N) m
var
% g' `/ d6 {4 y0 J* J' u3 i xbest,best_j:integer;
- L! z4 `7 G( {0 N! y$ V& Obegin
8 b' j, n$ i2 ~* X) n6 [, D- wfillchar(mark,sizeof(mark),false);
( A, [- e- R9 ]* D& Ymark[1]:=true; b[1]:=0;{1为源点} 7 f2 x- n) S, B% ] ^
repeat
& F6 c5 g5 D9 }best:=0; * t; D m# T0 K; `8 g
for i:=1 to n do
0 G% R, j( s% u* \If mark then {对每一个已计算出最短路径的点} 9 ^7 C/ l/ r4 r }# Z" W
for j:=1 to n do
. x- m c/ M) G# n( uif (not mark[j]) and (a[i,j] >0) then
, c! J5 V3 R+ t' h- u/ }, j3 k& _if (best=0) or (b+a[i,j]< best) then & l3 b7 f5 ?3 I
begin
" p- r2 @! ]9 K' ~best:=b+a[i,j]; best_j:=j; " s+ l5 \# w. s- q* t$ k
end;
2 p% b1 v. u7 \" i# kif best >0 then ) v8 ]* Y$ R( U) ]7 J
begin 7 |5 g3 S' a% G: T
b[best_j]:=best;mark[best_j]:=true; - D+ e+ ^2 w* j) ]) x2 n# M8 H
end;
* ?9 D) O- V$ P; C* A7 N6 \6 suntil best=0;
/ U, p4 X# }% e# t/ x/ \0 Rend;{bhf}
% `& D4 {) D) L4 s1 q/ h+ c2 t( |0 @# d: j; a! L
B.Floyed算法求解所有顶点对之间的最短路径: * y/ D4 e# Q7 {& L# x0 U( d
procedure floyed; # E4 i, X7 _+ q3 e' L9 z2 ?$ D
begin
8 v1 i$ g# d+ z$ c6 Cfor I:=1 to n do 6 y7 u5 Y8 q: I
for j:=1 to n do ' M' T8 E1 e3 X& p$ \2 `
if a[I,j] >0 then p[I,j]:=I else p[I,j]:=0; 3 {! \' _; [4 D) m6 g5 K5 ~
{p[I,j]表示I到j的最短路径上j的前驱结点} 1 g/ M: {- Y1 k9 G" j
for k:=1 to n do {枚举中间结点} & y3 h/ p4 S; H
for i:=1 to n do i# g* ^; X0 x" R1 R$ b/ r
for j:=1 to n do
6 |- n2 U8 q6 g- Y# {9 ^5 {if a[i,k]+a[j,k]< a[i,j] then 5 F C, V9 z/ f7 d+ [
begin % v( m9 R' p& d+ P: o( ?6 ?
a[i,j]:=a[i,k]+a[k,j]; - ` b2 c0 T6 l7 u
p[I,j]:=p[k,j];
/ m2 c! u# U0 V* E4 A7 u( Q: Jend; . W* R& G b$ ] h
end;
! s1 A- j- _6 nC. Dijkstra 算法: : s- W8 K" S0 ?* P4 k' `! u
类似标号法,本质为贪心算法。 " O1 l) w0 f! H* q$ ]
var
1 C) X/ v5 Q& k7 l) Sa:array[1..maxn,1..maxn] of integer; ! e0 G$ Q2 _( }/ x
b,pre:array[1..maxn] of integer; {pre指最短路径上I的前驱结点} - G" O1 C- t/ p
mark:array[1..maxn] of boolean;
5 i* O$ X/ p" d, ?3 L# T0 _& Tprocedure dijkstra(v0:integer);
3 ]" g8 x/ ^4 G6 }& P; q2 m# Gbegin ; c, P0 _5 p" g0 b
fillchar(mark,sizeof(mark),false);
" q) S9 f( a) r! ^+ c1 mfor i:=1 to n do 2 K. ^5 T2 ?+ ~" [+ k; q; n- T
begin 3 _$ Y) b( p8 e8 X
d:=a[v0,i];
& _' Y- b8 b2 }5 q" @4 r- p6 \- n Bif d< >0 then pre:=v0 else pre:=0; . f% k: q5 F6 Y$ y, i! k
end; 8 }6 g; w/ h4 x# ^5 @6 H& {6 t& R3 f% V
mark[v0]:=true;
0 A: O! a6 P) `( O' d3 S5 Hrepeat {每循环一次加入一个离1集合最近的结点并调整其他结点的参数} 9 B0 X4 r- t8 g( q# I
min:=maxint; u:=0; {u记录离1集合最近的结点} / \3 }6 n3 o {) s$ M8 V
for i:=1 to n do u' |. l! `( @7 m
if (not mark) and (d< min) then + E. Q! J$ m* ]# V
begin 8 _4 S# R* S1 K9 B- s
u:=i; min:=d; 7 K2 }' z+ Y8 S
end; 2 v1 ^8 x: t3 w3 j2 \" T+ U3 a
if u< >0 then 2 V) S% F9 K5 [
begin Z$ z9 R4 M) G
mark:=true; 4 e. G. x( {5 g( l7 \, P% }: v% v* T
for i:=1 to n do 7 X6 U$ N0 n6 @1 i
if (not mark) and (a[u,i]+d< d) then C6 v: c* c' N
begin
5 c1 k5 C& b$ l1 k6 f( id:=a[u,i]+d;
) T( w. b5 r, Z7 n( n0 X. Wpre:=u; 7 a+ k+ M; s( B: d ? i# P6 m
end; 1 ?, x" }4 O: @, H; r1 D& p, z" ?
end;
9 w8 K% s2 N; U1 \! b, B( |until u=0; / P, \8 L/ p4 U% r& X
end; ; W/ B- S6 R- S6 x6 v6 K. p2 ?) z0 @
D.计算图的传递闭包 * v3 R N2 H/ R- C/ H- b
Procedure Longlink; 3 R* p+ Z# ?; O$ e* @8 ?- p
Var
/ [7 H- b$ l/ n' _T:array[1..maxn,1..maxn] of boolean; - a' B: j& H8 e4 Z1 E$ t
Begin 6 ^: U2 E3 X/ V
Fillchar(t,sizeof(t),false);
5 T4 t8 l- n% ^8 EFor k:=1 to n do
; w- _* L' S k9 Q% tFor I:=1 to n do 4 n7 @7 g, d, R: |5 P1 L4 i
For j:=1 to n do
B, \( m: h4 c% CT[I,j]:=t[I,j] or (t[I,k] and t[k,j]);
7 y* N2 T7 n) r$ @: oEnd;
3 x8 ^ f6 T2 h- {/ g9 n$ A
& e* q9 q' S2 F6 P4 L+ ~+ F |
zan
|