- 在线时间
- 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.数论算法 8 V4 |8 ~! W0 C" U$ E8 N
求两数的最大公约数
- U. c. Z/ K0 [% H# ?5 Yfunction gcd(a,b:integer):integer; - w# m% H, ^% g0 B" u5 d9 `; R* S
begin
6 W1 A2 Z( z8 _- i$ J( yif b=0 then gcd:=a
6 C& z. \& ]* B7 ~* j( x$ @! Lelse gcd:=gcd (b,a mod b);
- i% B) s- ~4 N! M: send ; ; \' @, o2 w4 o& X" p. R) `
( g( _5 [4 s/ u. E* H9 h求两数的最小公倍数 8 s: z# a2 o4 e3 u& d. G0 e
function lcm(a,b:integer):integer;
9 K3 O) N( @. }3 w O( rbegin * G1 ^) N3 \: x" [, h4 T
if a< b then swap(a,b); 2 `1 m9 v- o$ Z
lcm:=a;
% V* Q: @# @/ P" o' ^% I& F/ N5 Mwhile lcm mod b >0 do inc(lcm,a); 5 E; T( W$ E# n% O- S! }
end;
' R' B' c' ^5 E$ d/ J+ _ o% O- {4 V' r) h8 r& C
素数的求法 9 M, M9 I) j, k: T: L
A.小范围内判断一个数是否为质数: * h) h. f3 W: R! f& m
function prime (n: integer): Boolean; 5 N3 B4 a- A2 x2 \
var I: integer;
6 R7 [- ^7 L! w* C$ _" U/ |begin
9 g; h6 B+ Q' k2 n$ @for I:=2 to trunc(sqrt(n)) do % M2 c7 U+ I6 T" l7 E. Q
if n mod I=0 then
- d$ C$ K$ I) r4 X6 J# E0 E& Y/ Dbegin s9 w* W) `2 T1 h
prime:=false; exit; & {0 }. z( ?+ H m
end;
7 k0 n7 c; q9 H- I- J& [7 M& fprime:=true;
, u: d8 s7 a( a: Z. O4 Lend;
' }0 s. z& @7 D }& y8 a
8 F( p8 i3 u# w8 h6 P" [B.判断longint范围内的数是否为素数(包含求50000以内的素数表):
6 N/ M. t# ~4 R- k# ~! ]procedure getprime; 0 c% i) W( |7 P8 o0 U) ]
var
& n& x" R: T$ R' d. F' Oi,j:longint;
) v, R3 ]! ]& Pp:array[1..50000] of boolean;
# p2 Y X3 W; s+ ]& sbegin + i8 s6 s L( @$ Z
fillchar(p,sizeof(p),true);
x) C' ?. I8 I+ G- p8 ?, sp[1]:=false; ( S! ] I- Y$ ~" ~" s5 L
i:=2;
! e/ a0 @& H' X* h1 T7 |. Iwhile i< 50000 do
, P `! g K$ \( l% l0 vbegin . x4 p. T& q$ C, X/ P. r8 S
if p then
% Q, U) X0 t3 n9 K5 tbegin 8 B6 ]3 P" d, { y1 i8 }) A
j:=i*2;
; O# Q% j1 Z, w( H) ^while j< 50000 do
% \3 J5 Z! i8 r* f, j! p0 F. vbegin ' W1 ^- W/ s, j1 u: o$ m9 A- W8 e
p[j]:=false; / Y* d( ~% q7 T9 S
inc(j,i);
1 F4 Y+ p% G: H9 Tend;
$ F" f" x1 |) A: Z; O Z2 pend;
0 E9 w+ @4 N$ H# B% [inc(i);
1 _5 M0 s5 |* G& F$ P( gend; * I* s( G/ J) M
l:=0; 2 |$ K8 o) |) d, f: n. Z9 @
for i:=1 to 50000 do ( l4 y$ e E& m! Q* | g
if p then
6 T8 J! U, Y |1 I1 ^( _' wbegin
$ [/ H" S; ~2 w$ B& g3 dinc(l);
5 n6 t3 M/ W5 F& o! L1 O1 Apr[l]:=i; 3 I' _5 z O2 O/ y( F; n6 m. {
end; / d# i' t8 t1 G7 m. B. s
end;{getprime}
, @& G. Y" r- E7 H* F- H {function prime(x:longint):integer; 1 z7 p& \# |9 U
var i:integer; 7 U+ H K. C+ b
begin
( M7 [( ~) s: o; M3 ]& Rprime:=false;
8 W" Q5 E, w Q% o( G! dfor i:=1 to l do ; t. U9 C5 W5 i$ s+ ^
if pr >=x then break n V( _( y; g% O0 ~# C
else if x mod pr=0 then exit; % i$ t G/ [( R
prime:=true; 4 _$ q- x, a3 f
end;{prime} w+ C$ m0 a/ T
/ W' y- l+ L. e& n* P
2.
2 l$ H8 R i9 l1 g* t# x- c9 C7 y, @ [* G7 t, n
3. $ R5 Z" i. h6 B# ?
" |' ^* d' l& [( P. x$ Y
4.求最小生成树
* y& C" }. t. pA.Prim算法:
* t8 h0 l: B8 t1 Oprocedure prim(v0:integer); 6 Z# D4 W! z) }
var 0 B L+ p' ?! v' n! O8 j
lowcost,closest:array[1..maxn] of integer; 8 j, I: h3 k x! J3 q( h9 A
i,j,k,min:integer;
! h9 k# \- x8 D8 Zbegin
- X8 i# q" `/ R8 L% R3 T4 Lfor i:=1 to n do % K7 _8 A) M5 I) M
begin
# x5 U. r+ J* F* J! n: `+ ~lowcost:=cost[v0,i];
, i" m# a" p* \closest:=v0; : d7 C7 h: q; K5 u' b4 z& g( d
end;
! G, W* K# ^: ~* u2 Kfor i:=1 to n-1 do
! K* k. z' B+ Q+ {+ e6 i" Gbegin
: k7 i8 A8 z t2 K/ b: g! h) r8 w{寻找离生成树最近的未加入顶点k}
6 U5 D, @3 }+ N9 c/ Mmin:=maxlongint;
' N+ u6 b+ X. p' w$ S5 Wfor j:=1 to n do
' X2 u9 i( R6 T u: lif (lowcost[j]< min) and (lowcost[j]< >0) then
& n. m: Y: e6 @$ g5 Wbegin 8 W7 @8 D) Z# _# V% h; b8 @1 a
min:=lowcost[j]; ; a% T: v2 G. f7 a3 p4 N
k:=j; 5 y; N% t0 H0 }/ h0 d8 f! {6 |
end; ; J+ h; t+ @+ D2 ?* D, u- m
lowcost[k]:=0; {将顶点k加入生成树} 1 g$ J' @* J) }0 r: D
{生成树中增加一条新的边k到closest[k]} - k; Y. \/ Z( Z Q
{修正各点的lowcost和closest值}
* c9 B& x- x# \- m V: kfor j:=1 to n do ! v9 L3 }; q+ ]# h' n7 M
if cost[k,j]< lwocost[j] then * Q& w& J- C( o* t8 T% B
begin
; c1 ]5 {( Y9 r6 M' o" w; O/ elowcost[j]:=cost[k,j];
& r' W) {% z) t; Q: X/ Z2 Q2 G/ aclosest[j]:=k;
# R- l, Q' D5 p/ Hend;
/ }' L+ a. K5 J4 W/ \& [end;
! Y6 T" z) Z; ]) L, g' G- W. d0 fend;{prim} ( I& q. t: Y' o" }) I7 T0 o' R
B.Kruskal算法:(贪心)
5 }7 s+ e; J- k按权值递增顺序删去图中的边,若不形成回路则将此边加入最小生成树。 6 v- Z, h2 {! w# n- k! q4 ?
function find(v:integer):integer; {返回顶点v所在的集合}
; t. i2 v3 v+ `8 Evar i:integer; 0 O: N) M, b, f% w) g: A
begin . n; e& C: L/ Y1 }/ t, N4 M
i:=1; 0 s( ^: _* v- v+ A0 L0 l0 i
while (i< =n) and (not v in vset) do inc(i);
( c7 O5 t E6 M/ Y. R+ qif i< =n then find:=i
* \5 ?7 x8 [& Y8 J7 selse find:=0;
$ [6 w2 o. S# U3 O! \end;
/ D& p7 m4 x1 A, H% K6 hprocedure kruskal; 3 m9 S$ H1 e& w$ Q/ f Z! s
var 0 a) K, @4 H$ W7 J3 |; w9 P
tot,i,j:integer; ; J+ J4 f8 C; L/ A4 d/ q0 K [- ?
begin
8 A( ~$ g8 [$ h' ^6 }for i:=1 to n do vset:=;{初始化定义n个集合,第I个集合包含一个元素I} 0 S& D; a2 M1 L+ G' \
p:=n-1; q:=1; tot:=0; {p为尚待加入的边数,q为边集指针} 2 B! l, w6 P6 R2 {0 @! B2 u- Z- {
sort; * @* X# J( v# a I5 X7 n
{对所有边按权值递增排序,存于e[I]中,e[I].v1与e[I].v2为边I所连接的两个顶点的序号,e[I].len为第I条边的长度}
: [5 H4 D; Q p% r3 ]while p >0 do
" L9 D0 \5 X1 S* A* Dbegin
) H: e# K: w: [8 ]& ~. [9 y! H6 Gi:=find(e[q].v1);j:=find(e[q].v2); : b6 X) P c W% z/ j0 d. M. u& G
if i< >j then ; E- _* D$ D$ [: F5 J7 N* G5 B4 R
begin
! y% P% b+ H" W" h# Z! }4 {8 uinc(tot,e[q].len);
y6 w' P3 w6 \& Nvset:=vset+vset[j];vset[j]:=[]; . d& N1 V$ F7 [% [4 p [$ y
dec(p); k2 f3 F; _# [
end; 7 b1 _- @- y- M5 A1 @
inc(q);
4 P o9 n! \/ s/ `7 A. wend; " f, t! r; y9 t6 n
writeln(tot); / d& R% Z8 m/ n
end; 2 e! g8 U& H; {
. E5 V- u# o* i8 N/ Q& y: z5.最短路径
- ]# {3 l& I, d8 Y, jA.标号法求解单源点最短路径:
( G' d2 R! s/ `& j# u, D) rvar
# f+ n9 P2 I2 ua:array[1..maxn,1..maxn] of integer;
- K! q! H. t7 A0 B! Mb:array[1..maxn] of integer; {b指顶点i到源点的最短路径}
9 Z& E( i; I0 K" B# P, J7 M# Hmark:array[1..maxn] of boolean; 3 ?( e! V7 _) q- f
$ @- j! o# f7 i! |, g- I
procedure bhf; * C( S* T; Y# D% K
var
: B8 r" C: F0 L8 Y: J( P, {2 Obest,best_j:integer; 3 M- j# \# d, [& z( L4 J% J
begin
5 v/ B& a0 q& {fillchar(mark,sizeof(mark),false);
1 a- D' u2 J2 y: N" q) H) _( \' Nmark[1]:=true; b[1]:=0;{1为源点} 8 E0 Y- l Y0 i0 r, a; @1 Y
repeat
3 M' U% d, E% I/ j% O0 A" ybest:=0; ; z' y- y# y% Z7 y9 Z
for i:=1 to n do - }8 w( u* ]. l3 G/ s5 V$ ]; @
If mark then {对每一个已计算出最短路径的点}
) j2 ?& Y; {) I$ j& U. B2 c0 e* `for j:=1 to n do
. ^# e; c9 P# \% qif (not mark[j]) and (a[i,j] >0) then - _9 P: r5 L) M9 [$ r
if (best=0) or (b+a[i,j]< best) then " U/ Z0 d. }& [- ^& y1 G$ x' [& y
begin
, r$ |) k8 s) j! _, u3 Z4 rbest:=b+a[i,j]; best_j:=j; : d0 I! v6 A1 F( b" n4 o
end; + z2 d+ j: k8 ]+ p4 X; b
if best >0 then ; y5 }3 b9 ^9 N+ [! D# r1 g
begin
9 l# W! _, z. {. B- h- S7 d0 ib[best_j]:=best;mark[best_j]:=true;
; M1 I/ o* e/ I, B* y! c1 M9 Pend;
! p, c2 y+ G2 J6 N8 {# Y& ?until best=0; . |* R3 `4 O! ]0 h7 D; ]0 q
end;{bhf}
% ?9 R3 q% r& j U* O# O% ? u! C
?2 r! y# _3 i1 }6 E# E# gB.Floyed算法求解所有顶点对之间的最短路径:
0 w' _$ P, k9 c( R+ V( i$ K- b' D! Oprocedure floyed; * [0 z L2 I% p& M, N! N$ }" {
begin 9 [9 R6 S) c, A2 i6 I
for I:=1 to n do & s7 y1 z$ M6 |. |4 P9 T& L
for j:=1 to n do
' c5 Z+ t' L) O4 V! Q- Rif a[I,j] >0 then p[I,j]:=I else p[I,j]:=0;
1 | I3 o: l8 n( ~! K1 \# I{p[I,j]表示I到j的最短路径上j的前驱结点} $ E/ Y$ a) p; E0 a \: E# s" x8 H+ ^
for k:=1 to n do {枚举中间结点} / p/ v6 a6 F1 Z, w
for i:=1 to n do
, r( H0 s, l- j: Cfor j:=1 to n do
& K X) C8 ?/ B% rif a[i,k]+a[j,k]< a[i,j] then 0 m2 S7 [. V7 X8 r. o; \
begin
" _2 i% t+ F2 F f* h# O5 |# f/ U! Ga[i,j]:=a[i,k]+a[k,j]; 5 a5 {' c a) a
p[I,j]:=p[k,j]; 4 |4 ^8 c: P" U
end; % w) f1 i7 r- T1 X
end;
- w# F' z$ Q; p: `C. Dijkstra 算法: ; d' Y1 g/ Y- F9 S l/ Q
类似标号法,本质为贪心算法。
3 l" c; X' G' F3 y; Y9 V ^var
& Y% y2 l! n5 Y% r. z0 E+ Ia:array[1..maxn,1..maxn] of integer; 5 h, q( z/ P! g8 v5 Z- y
b,pre:array[1..maxn] of integer; {pre指最短路径上I的前驱结点} " U' g0 I; s9 b
mark:array[1..maxn] of boolean;
! {; y6 h. N# `, K9 g$ Fprocedure dijkstra(v0:integer);
# M# l& c- I* W8 Ubegin 2 K+ c$ Z' G) i% Y' I0 q
fillchar(mark,sizeof(mark),false);
- B1 v. V& s8 N- }1 `% |for i:=1 to n do ' _, l8 Q: s' f' h, v( f, m; G
begin 5 w0 S7 V( q/ {; i, x' S
d:=a[v0,i]; # K6 x$ m; X& k& I+ e
if d< >0 then pre:=v0 else pre:=0;
0 A" I+ K' b7 _: A0 a" cend;
9 z8 E* b" o4 V: A5 y- _mark[v0]:=true;
, l: }5 i" t! G0 j% Xrepeat {每循环一次加入一个离1集合最近的结点并调整其他结点的参数} 9 J5 [) v' Z5 _; d5 L
min:=maxint; u:=0; {u记录离1集合最近的结点}
3 M) h5 U# T, t: W5 ~: m/ M2 ]for i:=1 to n do $ h) K4 k$ s0 {( h* @
if (not mark) and (d< min) then
; X. L6 \, m( l$ q+ nbegin
0 o) }" Y& a, Q. ?4 yu:=i; min:=d;
2 {5 S, [5 l, v* @% nend;
+ ?7 e. _; k. |% a: S& Fif u< >0 then 3 E3 }7 q% |- R- M" X
begin
8 N& _6 G$ T* p4 d! l6 H! Nmark:=true;
h1 m9 H6 K2 u/ pfor i:=1 to n do
9 m7 U7 {# S/ m+ y4 jif (not mark) and (a[u,i]+d< d) then
% t* _$ i S: }* n+ o0 \+ Cbegin
' u" n i2 V# F4 H; Pd:=a[u,i]+d;
" [5 j% T }7 ]5 Z+ B, {7 W. |) Bpre:=u;
. D: P1 \( k# I. W5 i& yend; 6 C- _! W" s& y, `( X; b# Y1 g1 H' T
end; : A" Y% E) u' A2 V
until u=0; + s j$ }9 f3 }. ~# y: v+ t, ^
end;
* S# s/ R& G" j# W& M% SD.计算图的传递闭包
! J) ~7 z( K% C% nProcedure Longlink;
% ?4 L3 J. n* m t" l* T$ C0 PVar ) i1 b( o* X' j- a1 f
T:array[1..maxn,1..maxn] of boolean; 9 V1 H7 _+ z" G8 X2 E
Begin
* p v) ^$ t0 Z3 Y7 u* TFillchar(t,sizeof(t),false); + k; S1 |2 F- n" G! E& h
For k:=1 to n do " i5 S% ^; v6 m% m9 L! h
For I:=1 to n do 1 d# m, Q `, k
For j:=1 to n do
0 }" g/ {9 E' l& z9 IT[I,j]:=t[I,j] or (t[I,k] and t[k,j]);
7 y" j+ N3 Y7 JEnd;+ A# E( F0 \5 g) B
% L- e% z1 e* `' D+ e0 B3 q2 [
|
zan
|