- 在线时间
- 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.数论算法 6 ~* u( Q( }& B- f, {4 b' j* f1 P: Z
求两数的最大公约数
) v. T8 p' B. o, A8 D* R+ e! tfunction gcd(a,b:integer):integer; ' Y. a$ k( T9 p' K" a6 C& A9 ?
begin
& l4 f/ O$ X- \2 }if b=0 then gcd:=a
& @" g" D4 e+ C% Aelse gcd:=gcd (b,a mod b);
e3 I6 }2 E$ }5 |end ; 9 x# g3 m4 B- u& D0 A
! m9 R8 Y4 O- k6 N. ]+ q
求两数的最小公倍数
0 b) u3 G8 F1 g' G& ?function lcm(a,b:integer):integer; ' W# y/ \& H1 T1 q
begin
% E7 y" @0 m3 V {if a< b then swap(a,b);
% h1 N8 D6 U- O6 H0 l1 s; ~( Elcm:=a;
) t* _1 b% X, c/ k; ^9 o N' k& j* |while lcm mod b >0 do inc(lcm,a); . h. Q( E$ `1 T8 x/ @- E
end; 7 I3 G0 [; H9 d, h9 l* l5 W
) U! }8 O- f1 T6 ^' w
素数的求法
2 z& r4 m8 A$ M4 a% L: oA.小范围内判断一个数是否为质数:
2 y( n" _% J4 j3 F! j9 [5 }! Sfunction prime (n: integer): Boolean; 2 {, m: e4 p# [# ^% c
var I: integer;
5 Q" `+ Q" g7 F5 @9 J$ o! kbegin
+ o# H2 c* @, t/ k5 e& pfor I:=2 to trunc(sqrt(n)) do
+ d5 p' ~7 M5 P( i$ Y& I0 ]0 Uif n mod I=0 then
. u* `$ P3 Z7 B* g5 cbegin 3 K: f& L f* F9 h3 G
prime:=false; exit; 1 h0 _9 ?, Z, N9 X& Y9 Z+ J/ {
end; $ w# d6 ~% W% b! A
prime:=true;
; v7 m' n" G3 ]2 q: R& Kend; ( K4 t; W5 J7 q3 ^1 a8 ~
- } n8 l4 w# Y- \0 sB.判断longint范围内的数是否为素数(包含求50000以内的素数表): $ r5 [& ~; ~3 @4 m
procedure getprime; & l; @5 l) o& F' J! d
var $ W6 G U& i9 o7 {( p1 O
i,j:longint;
8 m6 f4 J( Z! M/ R; B3 T' y/ ]p:array[1..50000] of boolean;
7 g0 f" d9 ?& Kbegin
/ o* [! A9 ?" i! r* W( dfillchar(p,sizeof(p),true);
/ @3 n7 I3 R& K& A$ r Z, H8 @8 Zp[1]:=false; : Z( q ~" f! ?
i:=2;
' R# N' t) O5 N1 Swhile i< 50000 do
" ~+ J& b* u: p. X# Y( Dbegin ( L% p. Y e m4 l
if p then
& k5 L7 e/ f" h! Kbegin ' j0 L; N: C" y1 {( [
j:=i*2; 7 W% q. n( k: b% `
while j< 50000 do : \. O; l/ P/ ~, S
begin " b) ?: K% F+ Q0 Z
p[j]:=false; 4 P2 R2 @9 T8 ~7 l
inc(j,i); Z6 ?1 o8 {! B# I
end;
$ i. k0 k7 z- Pend; 0 A ?% ]% m |0 L4 \
inc(i);
( ~) L' g$ J7 X$ r- M% Rend;
2 \5 }1 {- ~. O4 B, M7 ^l:=0;
7 |+ ?) z$ @8 n! X0 C7 nfor i:=1 to 50000 do
- w- ^! `, O1 {if p then
9 {. E, q, U7 o3 J4 m: h3 O Kbegin 0 X* G- @4 c! ^! f- p6 l' b
inc(l);
! Y; n- e* w# jpr[l]:=i;
1 i+ {9 b$ {: h+ j# f: Eend;
% y9 h) K# r' g+ L+ }, y) @end;{getprime} ! g& V; [+ b( k
function prime(x:longint):integer; & J" T* c. s2 [( h& o% D
var i:integer;
. n; U4 ^$ f7 k- z& u# h' \begin
2 Y& f7 u) u; O9 D8 B& s# jprime:=false;
6 e8 C2 p/ b7 }) O+ pfor i:=1 to l do
2 p' ^% _' n% R3 p1 F3 x& Y Fif pr >=x then break % i8 H# Y2 a t, V% @$ w
else if x mod pr=0 then exit;
+ c6 s+ X6 C+ f ]; rprime:=true;
5 l/ F! O& y% D; C/ c5 h6 mend;{prime} , J0 p" s4 y8 J9 [. e, k+ u
& B3 r* }( I/ B7 {; |# R2 y2. 5 J* m* e1 c+ d6 }! t0 x; V% O
~) }- t4 s8 j: d& S9 I8 Q0 }/ \3. 1 [+ S7 h7 f. F( {
& z; @ z9 }/ P0 X+ Y* k4.求最小生成树 - [; B1 |1 C8 I3 W
A.Prim算法: 9 t7 W, z. [1 x) O y% I J1 P \ S
procedure prim(v0:integer);
n% F1 C i5 X' i0 X& _' J( L/ @var
0 I d2 r/ k$ T5 V7 Y1 t3 ^lowcost,closest:array[1..maxn] of integer; t, c9 k O) n7 a3 Y4 @* W
i,j,k,min:integer; 9 K. W1 m! b. Q8 z( F
begin
7 O- @4 t/ y$ B- {* }/ q4 Vfor i:=1 to n do ; m- H V) b4 u0 G& |* x9 d6 J
begin
0 B1 k! o- O0 v# L1 G5 ]lowcost:=cost[v0,i];
4 N" r9 m' W4 R8 o/ x5 b7 u5 {closest:=v0;
& a- U. A; W" H& K# W3 {$ U& ?end;
# t3 c* i; I1 J/ qfor i:=1 to n-1 do . \( K: O6 D/ q* e6 v0 @6 G+ E: A: n
begin
9 D% g: E% V1 U# V4 C& v7 a{寻找离生成树最近的未加入顶点k} G: {: h* V5 V: n8 {' t: }: P
min:=maxlongint; , h8 T/ n! o/ ?. v7 V; l! O! ]2 y$ y5 p
for j:=1 to n do - s! f, D h0 w" u3 R; f9 U- T
if (lowcost[j]< min) and (lowcost[j]< >0) then
0 W6 j) O A$ U$ H1 G& Pbegin
. H0 K9 o0 d9 C% d5 x z$ hmin:=lowcost[j];
/ _# P7 x+ w* g+ a7 Y" F% h/ uk:=j; ; @" i2 L' |0 v' |
end;
: J! I8 P4 {1 n) i& Hlowcost[k]:=0; {将顶点k加入生成树} % s. V5 M" @+ U8 t
{生成树中增加一条新的边k到closest[k]}
9 `& D8 ~' v- ~& w{修正各点的lowcost和closest值}
k# a. k. ?% Y/ p2 ]6 u! Vfor j:=1 to n do
( R: a9 o" ~5 ?6 `2 P" `7 iif cost[k,j]< lwocost[j] then ! S$ i; O" b7 _7 g" }0 l
begin ! x8 j: z& ^/ I# y6 y( n
lowcost[j]:=cost[k,j];
% \3 ?9 ^$ s1 @3 ^/ m3 Vclosest[j]:=k;
, y5 i" j$ ^! [8 n" q3 ~end;
, `1 K. q& H8 z9 fend; ! u3 s9 u7 y( c1 Y, q# h
end;{prim}
9 e9 ^9 t# x$ `5 CB.Kruskal算法:(贪心)
# j, E; v& A; e) Z. {# V3 c! f( P按权值递增顺序删去图中的边,若不形成回路则将此边加入最小生成树。
0 ^2 R) m9 Z3 I8 J( Wfunction find(v:integer):integer; {返回顶点v所在的集合}
" J( G2 t- z2 E0 q' w. V5 _var i:integer; : p b4 }* M4 ^1 Q
begin
5 X m; H+ e3 o+ bi:=1; 1 o9 |6 S" X( J( O
while (i< =n) and (not v in vset) do inc(i);
, e$ Q" u( ~% o- }% @# Y( X* Jif i< =n then find:=i ) t2 H& _4 a9 T2 d$ T
else find:=0; 1 g2 `5 Y( i$ [1 I+ R: D+ ?# C7 _
end; * r6 v& Y7 b8 b0 M! w- b5 z
procedure kruskal; 5 _9 A( U1 u) l% R# y7 Y
var
) Y/ i* C9 L+ [- W0 ^7 T% G) etot,i,j:integer;
. r& R) L1 d" O" Z6 b5 O7 r+ Ibegin * i; e' e; d' o2 `
for i:=1 to n do vset:=;{初始化定义n个集合,第I个集合包含一个元素I} 5 E: N* \6 M: w
p:=n-1; q:=1; tot:=0; {p为尚待加入的边数,q为边集指针}
' x& G. w, _6 Ysort;
Z3 v: s; E( m{对所有边按权值递增排序,存于e[I]中,e[I].v1与e[I].v2为边I所连接的两个顶点的序号,e[I].len为第I条边的长度} 6 _8 ?9 V& f: X% _) y7 c
while p >0 do
* ~2 ]) A4 R* _6 p1 A2 Sbegin ) d+ I# V* a7 d
i:=find(e[q].v1);j:=find(e[q].v2);
4 x/ g+ ]* O" e: L; u+ Lif i< >j then . [' ^7 C. }3 |. Q" z
begin
: G I9 f+ J. u. y7 Rinc(tot,e[q].len);
2 s* p! W/ Z* Vvset:=vset+vset[j];vset[j]:=[];
& x* `. K/ q4 N% `; t. pdec(p); ) \: @2 f+ [5 ^' u
end;
& s" Q' E9 d7 h6 w; N5 kinc(q);
1 B* N( I" b! O5 W$ A0 O: g/ xend;
+ `: l2 \5 D- e6 S' j& i/ \& K# ?writeln(tot);
' l1 t6 d1 g- a4 Pend; 5 w) X4 R0 Q) m) U1 c; H4 l" ?' r+ S, S
6 l; [- k) ?& }0 A3 T0 H5.最短路径 - @: o p- C1 \& @0 `6 U
A.标号法求解单源点最短路径: - _8 a/ _" _/ u0 j5 Y/ S7 k: R; J7 e, Z
var
, [) \3 N& T$ N7 pa:array[1..maxn,1..maxn] of integer;
# X0 V5 f. k) qb:array[1..maxn] of integer; {b指顶点i到源点的最短路径}
! L, D6 A( R+ w/ ^; @( {mark:array[1..maxn] of boolean; * \3 P) ?( H) G0 s% K! U( G5 N
1 N( p, |% A9 g6 o: M7 h
procedure bhf; 5 W" P. L, L7 m
var ) c+ H+ ]4 Z1 F, d
best,best_j:integer;
0 }* @, H& }2 b3 T, ]' Y O$ ~9 A4 cbegin
. Q( S; Z# ?3 p; Ofillchar(mark,sizeof(mark),false); ' H* T" T) n6 k- {7 q
mark[1]:=true; b[1]:=0;{1为源点} * f+ `1 l; e$ P1 i0 y- b
repeat
4 f7 y7 q/ f w5 g! R @) J5 Sbest:=0;
) u' `* a5 e E: v# Tfor i:=1 to n do
: y [! x9 s! q2 W& w: }7 e' [! iIf mark then {对每一个已计算出最短路径的点} * Z' Q5 B! L* f' t( h" C! E
for j:=1 to n do
5 V/ g- _8 s7 {5 {4 G/ F$ eif (not mark[j]) and (a[i,j] >0) then 5 \8 u) ?0 L- X- g0 s
if (best=0) or (b+a[i,j]< best) then " Z$ l% F- |) i# g3 c/ K$ T
begin & I" @# M2 e# t5 r9 G7 R4 [2 V2 c
best:=b+a[i,j]; best_j:=j;
7 |& a9 V. i! b* _end;
* b- |' A/ C) k2 \if best >0 then , {& `$ W( |4 c' D5 U9 H
begin
6 r' E' \! q5 R) bb[best_j]:=best;mark[best_j]:=true;
0 O" J9 O( D7 M/ p+ Jend;
g/ }7 i* N/ \0 R2 Suntil best=0; 2 |* d1 A) e4 Y4 `1 V: Q" ]
end;{bhf} * S' n, @- w y( a
. r9 E. |0 C1 P0 {6 {! I8 p3 @
B.Floyed算法求解所有顶点对之间的最短路径:
+ w7 V$ C$ V/ W# gprocedure floyed; + \1 K4 }4 g* z
begin , A+ M" B6 |& {' n
for I:=1 to n do . C D! h1 D9 n& D0 C
for j:=1 to n do Y5 V! e4 ^( o
if a[I,j] >0 then p[I,j]:=I else p[I,j]:=0;
+ x. ~. H/ \ J2 h" M$ z{p[I,j]表示I到j的最短路径上j的前驱结点} + E- j0 S D, M" q/ N
for k:=1 to n do {枚举中间结点}
( m3 {2 K1 E1 ^ Wfor i:=1 to n do
9 u. u" q+ `7 @% xfor j:=1 to n do
% v4 w4 L! |( N, Fif a[i,k]+a[j,k]< a[i,j] then
Y7 t. t- m U2 N3 Ibegin - {! ?* d; P7 P6 Q* I
a[i,j]:=a[i,k]+a[k,j]; " } ~( V0 O( M# u, U; T, Q
p[I,j]:=p[k,j]; ) i( \! l' Q1 s# d/ H% D
end; ) b' F) D' q0 X' |
end;
8 F p" t# s/ Q6 eC. Dijkstra 算法:
/ S7 i# f5 C1 }: L" R- P S3 Q类似标号法,本质为贪心算法。
$ z( K) y4 X3 Q3 A7 n$ A/ y% q- I& N0 zvar
1 F U) B* h6 u) ^* e+ k: la:array[1..maxn,1..maxn] of integer;
' N3 l- H" Y1 @& Wb,pre:array[1..maxn] of integer; {pre指最短路径上I的前驱结点} ( \$ Q- S2 ?! R9 ~; z, d7 l5 i
mark:array[1..maxn] of boolean; # Q; i, Z/ V+ H, N( C, s& i& f8 x
procedure dijkstra(v0:integer); & }. m. s M+ S( t
begin & t& I, d0 o2 N3 f6 I
fillchar(mark,sizeof(mark),false);
9 C0 \; E3 {/ Q/ `, J& B$ H, @& i Nfor i:=1 to n do
( S# C0 W8 F3 D- e0 v# Gbegin : Z0 V" }9 B) D
d:=a[v0,i]; 3 |4 m# X( ~2 O) D$ z9 ^; r
if d< >0 then pre:=v0 else pre:=0;
: P1 R7 t, J w/ K. z& V8 Vend; 0 ?, g. E; g2 T1 C! Y* K7 {
mark[v0]:=true; 2 j+ O9 X" n6 B2 p* p$ K! Q
repeat {每循环一次加入一个离1集合最近的结点并调整其他结点的参数} - P6 i; n( t, ]) ^; h7 e
min:=maxint; u:=0; {u记录离1集合最近的结点} - v0 c: F' T( N3 R
for i:=1 to n do
! v+ |% a" Z4 w- {5 C* Q9 `0 |if (not mark) and (d< min) then + o! @5 C4 ?; N) ]5 {3 D# c9 I
begin
" E3 p, W9 f- o' H& }u:=i; min:=d;
% M2 ?9 U& }% a/ ]4 n+ gend;
3 b# ]! ^# t# @; E# ^$ cif u< >0 then
+ Z, T' q1 _. {* b& Lbegin
. _: g5 t9 ^0 Umark:=true; / q1 l! X* x. p$ G8 U
for i:=1 to n do
1 F# c: X! Q4 T6 q/ vif (not mark) and (a[u,i]+d< d) then
9 g3 ~% c; j+ `! S2 cbegin
: o% f$ ^" p# }; \- N6 pd:=a[u,i]+d;
1 S& @3 \! @3 x/ Apre:=u;
) h8 H- Q# ~! [0 b) F, Qend;
/ ]9 t0 V: j, d3 T0 @# S/ Send;
/ G* C" O, I0 q5 h) [1 B# T, ]: Cuntil u=0; ; ~7 N4 c( N9 ^) R( g
end; , |8 E7 I; N$ j( K. s' X( ~
D.计算图的传递闭包
W, V0 C# r/ M' ^8 S. J, EProcedure Longlink;
: h4 X7 u! V, @9 I; `! FVar 5 }" C: G6 F" R4 I1 _
T:array[1..maxn,1..maxn] of boolean; . w* ]9 f6 D- ]! I% p
Begin 3 B1 X) J% e, N! R
Fillchar(t,sizeof(t),false); . t l8 V$ \6 c7 y2 C/ n
For k:=1 to n do
8 E/ k' n5 Q9 H m( H, rFor I:=1 to n do
- }0 M3 @; r6 b+ \/ D$ \For j:=1 to n do ]- n x6 y7 a9 s2 }
T[I,j]:=t[I,j] or (t[I,k] and t[k,j]);
% p" g8 q5 a* P% b( tEnd;
0 j; U) S( C) E; z& @( `7 v/ J- q" b
: T: `; d$ M# Y) K6 c# ^; K |
zan
|