- 在线时间
- 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.数论算法 + V& _' H! j) h+ i2 ?
求两数的最大公约数
+ O+ t6 ^, W$ w' n5 o$ d. k2 v7 \function gcd(a,b:integer):integer;
. P4 d5 J$ V; C# i# f, V$ q% g; Rbegin
! K Y1 i; A, P J/ c2 J+ kif b=0 then gcd:=a 8 o* ~8 |' S4 i# c: `1 j& G/ |
else gcd:=gcd (b,a mod b);
0 t1 I: m; p0 X; a3 send ; ) s* c2 z. {9 w# j+ h
1 u# Q5 J# K! H3 o6 P; Y& w求两数的最小公倍数 ! a4 i6 P6 d* H9 @! }4 k
function lcm(a,b:integer):integer;
" p _6 e/ h9 H+ X/ D/ o+ U7 u& bbegin
- X" B8 q* J# l: S: ?if a< b then swap(a,b); % r3 W: I t* W+ d3 T
lcm:=a; # {1 a( n9 t7 u! g" h
while lcm mod b >0 do inc(lcm,a);
8 K- y6 T* `( W0 e, S" @( W& Rend; $ V" S1 a4 y# h4 A, P) O
4 v" i0 s9 W6 T6 w素数的求法 9 u5 {8 Z, H# {9 s- M- R, ]
A.小范围内判断一个数是否为质数:
) L+ j( P5 a& p+ a: Wfunction prime (n: integer): Boolean; & E! K3 Y, p6 m& E7 Z2 {+ E
var I: integer;
+ b1 L$ L) o8 {" Lbegin
, z1 C. A: F7 F" [$ sfor I:=2 to trunc(sqrt(n)) do % L* W4 a6 {: E% b
if n mod I=0 then 0 v2 |( ?; ?* C( a: _. n' n
begin
9 f E3 V5 j) V. bprime:=false; exit;
' p. ?. p' [( N$ w% K) l2 dend; 5 k3 h+ {0 P5 x6 o
prime:=true;
" a) r* P5 o# m) Nend;
; H9 c) _$ F) _2 @, u
3 l: z2 c: u; x5 [B.判断longint范围内的数是否为素数(包含求50000以内的素数表): % v* V+ @3 ]; {8 c1 N( |: q
procedure getprime;
1 b9 k8 y" O" z2 B, U2 tvar
5 `( H' C4 M9 M0 D$ z# X+ @i,j:longint; " C0 A# P1 M: i6 b% X1 z2 _/ z% q
p:array[1..50000] of boolean; 8 |2 H+ G6 y& A) N. N2 {; \# P6 p) M
begin
g% s( q; `9 K4 O$ M jfillchar(p,sizeof(p),true); R' g* l6 {7 R8 h) F
p[1]:=false; " ^; w7 x M# U: e6 k6 d
i:=2;
2 d- a# U; R! Z$ Lwhile i< 50000 do
) B& }7 C" t, @: | {begin ( J1 R/ W; f) {8 ^3 @- h
if p then
+ b- Q c, S: {% I3 Obegin ' w4 j N6 j7 r! C: c$ G
j:=i*2;
4 Q0 d+ S; |8 {! Q+ z5 D+ F& w0 Owhile j< 50000 do
& D# u3 A( A$ ]* C1 Dbegin
0 E' J# d7 G/ ?* ]p[j]:=false;
( G4 H Y; a; E" M0 S- G9 Qinc(j,i);
( t) J- P; G; b6 e( W+ aend; 0 v+ E# ~: u: d# j1 Y6 ]' s4 {0 _
end;
- s% i" M! d( h$ Q7 C: qinc(i);
' n. p3 _8 y0 s% @2 tend; , F U. c9 k& x& \- [
l:=0; ) v: o# h* w0 X) \- Z1 Y
for i:=1 to 50000 do
6 J' A& q. K4 z3 [if p then
- N, }1 S. R! I2 M% h: S7 J" E% x+ ~begin
3 d: k9 b% y; G; b: Ninc(l);
3 j7 g1 u9 G8 ~pr[l]:=i;
) ]( ~; q- i& \end;
/ s* r- V7 c& h: T' X# e" X7 E. ~. pend;{getprime}
) I4 n3 i8 C* _0 rfunction prime(x:longint):integer;
: g) T( b* k$ n, @ F& Qvar i:integer;
$ u) M& O1 u+ e1 }( k# Lbegin @: Z( |/ Z/ J B F- u" _
prime:=false; : L0 w" @$ X$ y4 E x' g8 i
for i:=1 to l do 4 |3 [) d" C9 V O3 ?# m
if pr >=x then break 9 G2 D6 M$ S- C
else if x mod pr=0 then exit;
; L5 Z# R: Y, j$ r# fprime:=true;
' H- |; W0 R8 M% r% h# oend;{prime} 1 G! ^' n! }0 o* B, \
% b0 `* E, ] H, Q% @2.
: e0 P/ F" |7 S. `) r' x5 |: F7 {, b$ p, q3 c: B
3. 5 A- N3 _1 j7 O0 Y. ?9 j9 G2 B0 M: Q; Z8 Z
$ i/ y+ n" o, e8 C5 P8 c* i4.求最小生成树 ! h/ I$ m P3 `9 B6 |( G4 U
A.Prim算法:
}2 n! ^: X' ?+ U& j4 Gprocedure prim(v0:integer);
# W& K0 I7 p. ~, y$ u" u5 H! R" kvar
- o( G/ s0 }$ P: Klowcost,closest:array[1..maxn] of integer;
( f- C; S7 O: P$ R9 ii,j,k,min:integer;
. } v: ^" K7 d! {begin
( v N5 R+ Y2 K9 ?for i:=1 to n do
$ k G. s$ m! ^begin # Q# {3 p0 T. j3 Z: Z& B
lowcost:=cost[v0,i]; - s- B8 ^1 c# \0 P0 M# H
closest:=v0;
+ G: X8 M7 r: K! D0 p ?3 y9 cend; & A4 X J5 y0 t( P; s8 L- F
for i:=1 to n-1 do 0 {$ K- M; v$ U8 G s
begin . O: [; p8 P5 S8 M! K c
{寻找离生成树最近的未加入顶点k}
3 x3 ?4 d l7 N+ \5 }8 |1 G+ Xmin:=maxlongint; " Y1 _8 J! k3 y- b( Z- t
for j:=1 to n do
a. Z8 c7 L& m. q) o1 Cif (lowcost[j]< min) and (lowcost[j]< >0) then
2 F" g$ v0 t( U: t- Ybegin 5 |/ v H3 ~& n% r
min:=lowcost[j];
2 t: e- _, |8 H( R9 b" H3 Ok:=j;
5 T; x, F' J9 ~- Send;
: w) `% e8 r; V6 d% j# vlowcost[k]:=0; {将顶点k加入生成树}
u6 s: _) X* F{生成树中增加一条新的边k到closest[k]} . `' E' t) ]& h$ Y/ S. M, b
{修正各点的lowcost和closest值} : Z C% y$ }! A5 L- @% i M
for j:=1 to n do ! U! V; g; q( r. ^, X Z
if cost[k,j]< lwocost[j] then
9 G8 k2 Z1 X# D- |( X& b# tbegin
, Z3 j( D& A. P% Plowcost[j]:=cost[k,j];
/ q$ K' {" F! x. N7 \0 B5 eclosest[j]:=k; ( M) j" L* D. H8 w
end;
5 o) D# f9 S4 V" cend;
$ b; _$ x; i& `/ `end;{prim} ( y8 y l, }. J9 U) x n
B.Kruskal算法:(贪心) 1 b% [+ u; E7 W5 f" Q9 W9 G8 f# L
按权值递增顺序删去图中的边,若不形成回路则将此边加入最小生成树。
, d$ l3 l: p% r. b1 Gfunction find(v:integer):integer; {返回顶点v所在的集合}
% e. f' H4 V: r Xvar i:integer; 4 C4 G+ S8 H. N& V6 R. x# \
begin 8 o9 `0 C ?4 W! |" C# i
i:=1;
& y! ]- _, o9 t8 I2 vwhile (i< =n) and (not v in vset) do inc(i);
8 l8 N2 y; ]$ q5 K3 Mif i< =n then find:=i
/ F& R8 \5 S' B7 Celse find:=0; ' D% ]+ G6 `; A! J" D5 z9 T. y
end;
+ ] ]) S0 D7 z! m2 I- ~4 Fprocedure kruskal; . @/ h6 }, j$ _4 n# F- g
var
- Y; `$ k) h7 u# ]% w3 [8 ftot,i,j:integer;
! M. h9 L, V) y, Z9 x1 {begin
% ^ H+ |/ H* k( hfor i:=1 to n do vset:=;{初始化定义n个集合,第I个集合包含一个元素I}
$ _+ D* _. [" R, Y5 b6 hp:=n-1; q:=1; tot:=0; {p为尚待加入的边数,q为边集指针} - [* ~" v- h3 n
sort;
- r- k; s$ p/ w4 w: P{对所有边按权值递增排序,存于e[I]中,e[I].v1与e[I].v2为边I所连接的两个顶点的序号,e[I].len为第I条边的长度}
( D+ P( |; W6 c& N6 {+ v- Rwhile p >0 do 9 I8 G- ~5 c7 @" W3 K# B
begin ' V& [' Q, M$ H$ ?5 g. O/ s
i:=find(e[q].v1);j:=find(e[q].v2); 2 a/ L0 G3 X. Q
if i< >j then
. a6 _: G2 H" p- cbegin
. O$ C! n& y$ _) u9 Ainc(tot,e[q].len); ! j2 P, g! a( j' B# @4 @9 v
vset:=vset+vset[j];vset[j]:=[];
5 S( x& K% u, m' w C, O- Idec(p); 0 I0 w& G+ q2 _+ I& [
end;
4 L' q# @# O6 G: Xinc(q); & \: d! x* h& j* M
end;
; u3 g/ d& ^4 @9 d4 c; O! Qwriteln(tot);
0 Y) K3 I' W' D1 N: Aend;
2 a) c( s2 K9 n7 |0 O. T6 A( o. P
6 Y4 k7 e3 ?; a- G1 W, F5.最短路径
! r4 i) X; S' r- {A.标号法求解单源点最短路径:
: [. Z, k8 I r D7 M" |var 8 H. W! C, q5 k
a:array[1..maxn,1..maxn] of integer;
& v1 k# I: I! W) Ub:array[1..maxn] of integer; {b指顶点i到源点的最短路径} ! r% I# T% x! r9 Y& f* ^% T1 |6 I
mark:array[1..maxn] of boolean;
% o' }- P" |/ ]: ~* c; g* r" U$ G* X0 l. ]+ g1 N
procedure bhf;
/ j7 ^# y( S- A4 gvar
5 O! I" B5 U4 v; Cbest,best_j:integer;
. U1 h2 m, E S- V a/ Ubegin
6 @3 v5 V/ G. p* B5 K' d8 Ifillchar(mark,sizeof(mark),false); " T! i9 _: ~; u2 }4 v
mark[1]:=true; b[1]:=0;{1为源点} W K+ P$ E+ w& Q# v( V) X
repeat 5 |3 ~0 k7 c8 M- H6 [) o3 K
best:=0;
8 b0 j# @: T n7 L9 U2 `1 i8 \- ifor i:=1 to n do - c9 B3 P3 X+ d
If mark then {对每一个已计算出最短路径的点} * z, D# j( z" ]* Q. s( e
for j:=1 to n do . D- t9 I; R8 G. a7 e+ n2 i
if (not mark[j]) and (a[i,j] >0) then
- w$ ]7 V( @3 t) `if (best=0) or (b+a[i,j]< best) then 5 P" Y H# e6 F% S) C
begin
( a; E) R$ O; g/ s6 w: rbest:=b+a[i,j]; best_j:=j; : v0 t2 G9 Y- w- `7 ]; S
end;
6 c! g$ o6 x! ?2 u; D- j' qif best >0 then 4 W0 l! h; h4 @6 _; Z
begin
# f- V/ b! h, Z# [$ a: D4 Wb[best_j]:=best;mark[best_j]:=true;
( o" ?9 k' Q2 ?& y# uend;
* H9 ?3 o; M% z4 n& \until best=0; " O; v. {5 X* r: Q
end;{bhf} 6 p M; P; U& t' G" @
$ P) H/ ?( k; x" R# \B.Floyed算法求解所有顶点对之间的最短路径: ) q* {) L2 w0 z. R6 ]
procedure floyed; 1 F8 O4 X& d3 ]. H P5 E
begin 9 `) G5 f u& N6 z3 S7 K/ T0 j
for I:=1 to n do 0 q& X" N4 J+ B9 ] u& H- b
for j:=1 to n do % `. J' f8 Q( P
if a[I,j] >0 then p[I,j]:=I else p[I,j]:=0;
; ~/ F6 u4 C. j{p[I,j]表示I到j的最短路径上j的前驱结点}
% E B' t& Z* Rfor k:=1 to n do {枚举中间结点} ( G, {0 W+ a9 {: C2 a
for i:=1 to n do
+ b* n3 A( w4 Nfor j:=1 to n do
$ Y9 R x7 Y* r1 P- oif a[i,k]+a[j,k]< a[i,j] then # ?( `+ [* ]: J4 x$ r
begin + I- j5 f* J k0 n" S
a[i,j]:=a[i,k]+a[k,j];
/ I Y6 `2 u6 b- x5 Q: np[I,j]:=p[k,j];
' b2 e1 e, j. \" ?& ^2 ]end; 5 j3 F8 v3 A# A5 u! a
end;
! Q/ G* f7 U; q* j) f' o9 xC. Dijkstra 算法:
1 e: j+ F: R- l+ d类似标号法,本质为贪心算法。
* V- \ F @/ b$ Dvar
9 I; ^0 I& x4 K* ~- s0 @2 Da:array[1..maxn,1..maxn] of integer;
8 i2 R: Y, T1 @$ kb,pre:array[1..maxn] of integer; {pre指最短路径上I的前驱结点}
2 W5 M" E/ W( Q# `' b9 Ymark:array[1..maxn] of boolean;
& z+ a- M+ g% s6 pprocedure dijkstra(v0:integer); ) v8 y/ L# o- F1 T, w: Q
begin 6 v" b. i9 R0 Y. u
fillchar(mark,sizeof(mark),false);
v$ w. e, j8 pfor i:=1 to n do
* u* U- O9 W! c( T- |4 sbegin
( g' _8 C( L4 W- w- Z' X( w; W! Xd:=a[v0,i]; ; ~$ C+ U4 Y" [
if d< >0 then pre:=v0 else pre:=0; ) K7 @( g N; V$ i
end;
( w: @0 d: V* n X2 Bmark[v0]:=true; ' y6 c+ Z) _6 \4 d" v3 l8 z
repeat {每循环一次加入一个离1集合最近的结点并调整其他结点的参数} : }; t% z, T, A' h: K( Y
min:=maxint; u:=0; {u记录离1集合最近的结点} 5 n9 ?" a) g0 n! Q
for i:=1 to n do
* e# E6 H6 f' _if (not mark) and (d< min) then V, H! s8 q5 o/ n6 y( v
begin $ M4 D% V4 S0 `6 T% ~
u:=i; min:=d; / P; n; [- |# _6 K
end; + M* O6 h$ c+ `1 @
if u< >0 then
7 n- x0 [7 e0 [0 Kbegin
) Q. M$ `7 a1 @# r6 S) ]0 rmark:=true;
+ W. y, ]( V2 i2 Z' tfor i:=1 to n do
1 J: z) h) [5 ]1 w7 O; K& G( bif (not mark) and (a[u,i]+d< d) then & H! q) }8 l i$ i+ N. `
begin 2 x4 F H" a# |- v
d:=a[u,i]+d; . J* k: |: m# k- H% P% e( q7 [9 d
pre:=u;
D& V( o. C4 f7 ]. `: Gend;
: C# M5 g/ {$ W1 Aend; # ~1 P0 u* z0 j5 ]9 E+ E: }
until u=0;
; A( T {$ k9 u4 K' iend; 6 y& t" x* {% j8 F% x/ H$ m* A
D.计算图的传递闭包 " l! A5 o( h# U* @# Y) x6 C
Procedure Longlink;
: B* w# G: y( t0 PVar , N" U }- `* P
T:array[1..maxn,1..maxn] of boolean;
! b& M/ V6 Q6 Z( ]# Q9 Q/ `1 ]7 XBegin
0 p8 U: U5 w7 z& _( _1 C" dFillchar(t,sizeof(t),false);
: Y6 @' d9 d. B7 q7 T4 OFor k:=1 to n do
$ p0 I" V8 y+ a- rFor I:=1 to n do + o0 d! Z: M# V0 H$ D1 A/ L& B
For j:=1 to n do ' H: g5 P2 z1 K' @7 b( s8 f
T[I,j]:=t[I,j] or (t[I,k] and t[k,j]);
6 s, l3 N( i& C; sEnd;
* o; D6 H! J' N% n7 L* S4 k$ `! a7 l% Y5 ~2 K, w
|
zan
|