- 在线时间
- 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.数论算法 # U6 \8 _6 h) ~$ p" f7 }' o
求两数的最大公约数
2 ]+ t( s' Z5 X4 I wfunction gcd(a,b:integer):integer; + J1 O/ r: X, t1 M) p
begin
5 B/ H& Z6 s* }/ j! D% F1 Wif b=0 then gcd:=a , ^6 `; L/ w$ R6 @/ ~4 E" t
else gcd:=gcd (b,a mod b);
& A- p/ O' ]$ F6 ?8 t7 a0 r+ hend ; . ]; F+ _: k% o7 X! r0 @
9 s3 J: F! h6 b2 C5 l3 j+ C求两数的最小公倍数 + r* r% e8 _" j8 j6 V! E8 S, O2 ?
function lcm(a,b:integer):integer;
0 Y; }8 ?" w. \' v0 jbegin
# q3 J, R- x" v0 B" w ]" O9 B& wif a< b then swap(a,b);
. P' {# V. j* d) L: N2 V$ f5 t: k$ jlcm:=a; 6 G" Z* f+ e) \! [. [; Q
while lcm mod b >0 do inc(lcm,a); : C1 \ C8 t) b i
end;
* C9 |5 P% }6 ?0 C6 Q- G2 n6 Y0 v6 M$ J) G, H) n
素数的求法
* ^- R* F3 V, \; o: kA.小范围内判断一个数是否为质数: / U1 M0 I2 P8 t
function prime (n: integer): Boolean; 0 Q/ O7 E! Q( ~
var I: integer;
2 I: w' e. ]6 K8 @$ D O% y) abegin
& W: H% v( R7 Q9 N, |6 vfor I:=2 to trunc(sqrt(n)) do
" G' \0 i/ K# o6 x Vif n mod I=0 then
+ F. k9 u {9 Y3 f* |6 d: jbegin # _0 {% [, f% Q/ {2 \
prime:=false; exit; 8 t j# y2 H# G" u
end; - O3 e. O- z: M# I; B. S
prime:=true;
% w% J) _4 d- G6 q6 D3 `end;
9 B+ l) U, h D6 S/ m* F6 u. l! ^
" {/ h1 Q b0 e" x, M2 { B) wB.判断longint范围内的数是否为素数(包含求50000以内的素数表):
. ~% j) |8 o$ G" E x2 P! @procedure getprime; & a$ f4 I1 L& R; c& e, t4 Z* ^. y
var $ [ a* D8 D+ f K' S
i,j:longint; 4 ^' o M# J+ Q: }& y' o5 [# g, O! t
p:array[1..50000] of boolean; 1 t% J, U1 j3 t( p: o/ J
begin ) g7 W6 `/ A: M. b
fillchar(p,sizeof(p),true); : _" k$ n. e5 C! W
p[1]:=false; 1 N/ O0 f P5 J1 ~' h# G
i:=2;
( M+ i3 {4 y( M; j6 f/ Jwhile i< 50000 do 2 E% U# s2 _3 X
begin
9 ? J) j5 T( [# x* Qif p then
% X' d! ?+ ?( y1 V0 Pbegin ' y0 Y7 l+ W2 a7 C2 z+ z( \9 v' ~
j:=i*2;
. s+ S8 Y" _9 N) H5 e9 Ywhile j< 50000 do + U' y! g" O! _, K* z; d% q
begin 7 J% m! s! s( q- n- y. A |) R1 l
p[j]:=false;
5 W/ s# C3 B# a) t7 y1 j, D& qinc(j,i); * o; b% E& d$ C6 R0 t& e: P$ H
end; ( I% }3 d* P+ Y* m$ n# b
end;
: z; D: E% {, k) Sinc(i); $ U/ G5 a* R7 W
end;
7 V+ j5 f$ c) j% l# il:=0; 6 \7 Y6 y, Q% [
for i:=1 to 50000 do 0 \5 r; y+ w6 T$ y4 w
if p then 7 V. h& V# N4 F' Z
begin + K5 e, k; M: \9 R
inc(l);
8 P h# A4 \+ e, Y9 D" R' G) j# v4 Bpr[l]:=i;
4 o2 S6 @5 C0 a" j9 G7 f; U9 [2 V; v4 gend;
Y: Q; F5 N. S2 E* t8 D0 kend;{getprime} 7 v' ~6 {' N9 U% r
function prime(x:longint):integer; 2 i& |+ [8 s* g$ t& Y1 p
var i:integer;
4 o, C2 ?8 S# F0 J9 w# X9 }begin 2 q" p3 P; H/ v5 e; p* w/ h
prime:=false; # H w/ X* _# r* j, s: F
for i:=1 to l do
' ?! Q6 y) B# x/ b( N/ Iif pr >=x then break 6 l, v2 J4 K5 `
else if x mod pr=0 then exit;
; C6 x9 w. |# E0 i) W; Hprime:=true; 6 |6 l/ }+ L: |# b
end;{prime} ' \" T7 w* F7 I- Z2 p
6 r) A+ N+ t5 X S8 D( ]6 ]/ j
2.
$ e4 n, c7 t% y. o% \- { Y
& }# d9 F4 e6 X' T3. : v$ E: V; b4 m$ M2 g. S
& u; Z( w' ^1 D" _# I7 k
4.求最小生成树 ' |+ n; {" U* a/ c7 g h
A.Prim算法:
- @$ U _4 G# r4 ~( l kprocedure prim(v0:integer); " ^; l! ^' ~( G$ P# r
var ! G& ]/ U, a' \6 B( V
lowcost,closest:array[1..maxn] of integer; # V7 R. a1 P; W( w5 N0 ? V
i,j,k,min:integer; 3 ?/ ?4 u9 h1 {1 p/ W
begin . A& f5 E# f+ O1 k( m4 N$ f9 }0 p
for i:=1 to n do
2 z3 Z9 Z$ ? X( z! Abegin
5 i& K9 ]2 x% C. m1 T& M- p& ilowcost:=cost[v0,i]; - w- p4 Y) x2 Q/ {) G. a1 n6 S
closest:=v0;
o+ c- d' P" K- E& i/ R" ]9 ?end;
/ \$ r5 }- k8 h( @for i:=1 to n-1 do
5 p7 j; s2 W; _; e5 u6 K# Rbegin 7 S9 A: V0 k6 Y+ Y% G- n' h" p9 M
{寻找离生成树最近的未加入顶点k}
J6 P( T+ H8 g" r5 M5 b& bmin:=maxlongint;
4 V& Z# [7 n: C) Pfor j:=1 to n do
2 |& k7 {4 P: v% qif (lowcost[j]< min) and (lowcost[j]< >0) then
?1 D! H8 z9 H0 W, n, `* S1 Xbegin - j4 {: a0 Y9 y5 p1 ^
min:=lowcost[j]; ) N5 t. g, P; Y- B# O1 V6 m; }8 B
k:=j;
. L6 r1 Q/ P+ Y$ S: |end; ) F8 U& B* I8 I! ^7 j/ ?
lowcost[k]:=0; {将顶点k加入生成树}
5 E4 U! J; @* K{生成树中增加一条新的边k到closest[k]}
# L( J7 o0 l7 M$ V1 ]) U$ p{修正各点的lowcost和closest值}
: Q; m$ W7 k9 r; u5 ~2 ^for j:=1 to n do 2 T. ?5 Q# r% K" g8 l$ e2 Y
if cost[k,j]< lwocost[j] then
( z4 J9 s9 a. ?9 i# Vbegin , e, H" z7 Y$ p
lowcost[j]:=cost[k,j]; / ?: b0 J7 q. A) n
closest[j]:=k;
; o& V: c- F; gend; ) Z6 a- Y' ^4 E2 z2 v4 w( ^
end; 9 ] m( z$ ~6 d! h4 |$ R7 \
end;{prim} 3 t4 X% }2 O5 ~
B.Kruskal算法:(贪心)
+ R2 |8 {! n* g+ ?按权值递增顺序删去图中的边,若不形成回路则将此边加入最小生成树。
5 w9 r, f4 V5 F/ f( Afunction find(v:integer):integer; {返回顶点v所在的集合} - M2 f/ m; U1 R1 _
var i:integer;
9 }1 O) y* D W/ n9 C! n# cbegin
' s3 V- ?: ?) [1 B* Li:=1; 7 ~( i4 v, n, l/ c; H$ u. v5 H
while (i< =n) and (not v in vset) do inc(i);
1 b) M2 D2 X6 N! P3 O6 f1 a& Qif i< =n then find:=i ) ?, q+ C# G. Y# j( m! E m
else find:=0; 1 \, [8 [7 p1 D) q
end;
" ^) e! t K$ z3 S. z/ K& sprocedure kruskal;
# y3 h2 l) ?6 b0 }# S+ X- }var
' v$ n9 G+ s6 wtot,i,j:integer;
, |. g: v" P( [/ z( Cbegin 6 v" \' d* e1 v/ ?/ b
for i:=1 to n do vset:=;{初始化定义n个集合,第I个集合包含一个元素I}
* H. R6 o, P, }( r+ ]+ k+ O: f- {p:=n-1; q:=1; tot:=0; {p为尚待加入的边数,q为边集指针}
9 T* M% w8 M% J- e' Xsort;
+ _: b; v& R6 W/ I$ U: W) U8 k{对所有边按权值递增排序,存于e[I]中,e[I].v1与e[I].v2为边I所连接的两个顶点的序号,e[I].len为第I条边的长度} * l, t3 S+ a8 W' Y+ ^% K* H( b
while p >0 do & Z* o! ]5 g. I ?, |" K
begin 4 N; Q" _6 B6 d$ `4 K
i:=find(e[q].v1);j:=find(e[q].v2); # e+ [2 K) C" X" E# ?
if i< >j then * f: e9 ^9 _5 w6 g
begin 0 [; |; W5 h! O4 i, A. S
inc(tot,e[q].len);
q# t w5 O2 v5 |3 Kvset:=vset+vset[j];vset[j]:=[];
4 n1 q4 Y2 c: N8 i( X: e+ k; Cdec(p); $ e) k* v# c( Y. P' W. T
end;
/ D, L1 D8 {- Q+ Minc(q);
: r+ a( O& ^' A; N9 D- d5 O( xend;
6 w. A( {9 n" V7 W" g' C) a! _writeln(tot); + a7 m0 h) j; g N9 z+ \% c
end;
; k' U) F: a% ~) \3 M- J9 O( s$ m! H) A
5.最短路径 $ M' j$ D l7 a/ Q. b$ ?# X: |6 t
A.标号法求解单源点最短路径:
: S8 U) \# z- {$ Ivar
. n0 n9 a% w. k3 |. A2 Qa:array[1..maxn,1..maxn] of integer;
9 N/ Z, g: @& J- J" ]6 }' Tb:array[1..maxn] of integer; {b指顶点i到源点的最短路径}
}7 R3 z) U, _; N5 Imark:array[1..maxn] of boolean; . T/ {7 t1 ^# H8 h
: E' A: S! m# f* a1 B
procedure bhf; 5 X7 k$ |8 ]3 D. `
var
% v3 e! {) f& N/ Wbest,best_j:integer; & t }0 Q- r U1 L3 H# k
begin
1 H/ g& U0 J$ T# J: yfillchar(mark,sizeof(mark),false); 5 `/ r; w+ b& n' {& P) Y! b5 e' ]
mark[1]:=true; b[1]:=0;{1为源点}
8 l8 s- v7 e* ~; a2 q4 B: t+ c/ nrepeat
6 x1 j: Y6 {: i2 z+ c9 |+ }best:=0; " |/ x/ d4 _0 ]2 y5 v% G+ i( I* V/ l
for i:=1 to n do
3 | S7 [+ r* U ]If mark then {对每一个已计算出最短路径的点} {6 ~& X f4 }
for j:=1 to n do
! y( ~# @8 I8 `! Nif (not mark[j]) and (a[i,j] >0) then
k7 A, I; U) I d; K* E- G8 U6 gif (best=0) or (b+a[i,j]< best) then / A. K w2 q' l a# D
begin
; [" r9 w; `( r/ m% \' D* Y% i( x* obest:=b+a[i,j]; best_j:=j; E6 o9 b! D( ?5 @. E2 E( }0 M
end; , Q4 s3 |% c" q! a
if best >0 then 0 G, E: E( d6 c6 v- b
begin * I2 ?! T+ G3 \
b[best_j]:=best;mark[best_j]:=true;
+ h% T) G2 v$ F4 G8 B1 }! P: {end;
4 W$ m; ?9 W2 z6 ?until best=0; ' m; X2 P8 @/ Y3 L# R! y; ^
end;{bhf}
) f/ R: j! J- V/ `4 w0 g0 K
2 G/ D4 z5 w; ]6 i* eB.Floyed算法求解所有顶点对之间的最短路径:
8 Y/ o4 o% p) ?! d: w- I3 @procedure floyed; 3 h* E! d9 ~! L3 ^8 m6 c
begin / F* l4 c9 k: Y
for I:=1 to n do + m/ K( S* X# |
for j:=1 to n do ! O* k3 j8 Z9 r' }9 _+ l; k
if a[I,j] >0 then p[I,j]:=I else p[I,j]:=0; $ R, Y- C/ V# X' e/ Z: ~
{p[I,j]表示I到j的最短路径上j的前驱结点} + V5 ^2 E. m* w. Z! Y
for k:=1 to n do {枚举中间结点}
; X k6 a. M g$ [$ A( `for i:=1 to n do
0 _/ c7 W' G3 P7 R% ]# |8 W6 G2 zfor j:=1 to n do
; u7 p2 l1 q: Cif a[i,k]+a[j,k]< a[i,j] then
, ?$ S! N6 W- j" i0 Y6 N/ ~3 J% n" Zbegin 8 j. L% H/ R2 ?+ {1 B: {0 o [
a[i,j]:=a[i,k]+a[k,j];
6 S8 j) y& ]& p# Y* c+ Up[I,j]:=p[k,j];
9 f3 x- a! K8 c- g2 b: Qend;
' X" Q- h9 [, { s. P0 L/ B, v Hend; " v- N) I, P* m* Z: c
C. Dijkstra 算法: # a5 m4 B$ O& x N5 w" X3 m
类似标号法,本质为贪心算法。
4 U! a0 T& K1 Z" qvar
0 G5 ^6 o. o' Ia:array[1..maxn,1..maxn] of integer;
6 m% S2 ~" M2 qb,pre:array[1..maxn] of integer; {pre指最短路径上I的前驱结点}
) n$ b. V( v _8 P' D; q$ fmark:array[1..maxn] of boolean;
$ `4 \7 R* X' \( x: Xprocedure dijkstra(v0:integer);
& i9 l- B) W x" j7 c; b& ?4 Fbegin & M' L B" [) i. Q
fillchar(mark,sizeof(mark),false);
% b; o, ]7 _& ^ J& `for i:=1 to n do
& @+ W( |; s8 P R0 t+ k: Pbegin 2 X3 l7 V l% ~1 P; s0 Z
d:=a[v0,i];
! r- m# _# t6 h8 ~4 U5 Nif d< >0 then pre:=v0 else pre:=0;
0 u" E( w8 v5 p$ vend;
: E" S/ x9 }# G: I0 J& d: xmark[v0]:=true;
4 F N4 _ B/ l/ d3 g6 f) lrepeat {每循环一次加入一个离1集合最近的结点并调整其他结点的参数} , n3 A" _6 \+ m+ a0 W: l
min:=maxint; u:=0; {u记录离1集合最近的结点}
2 {& p5 s% g. _ Z+ T- d& M) Hfor i:=1 to n do
& x! s& S: i1 a2 i) K7 A1 Qif (not mark) and (d< min) then
^4 J& p/ Y( ^' [/ I4 J$ obegin
4 l5 H4 N+ w* Z3 y1 m6 ?* B( M3 r% wu:=i; min:=d; \$ E' j" H3 I
end; ) F0 O; V. L+ m* Z
if u< >0 then 7 r2 `8 K9 Q) e# u7 A9 c5 u9 n
begin 6 H8 {. R( _3 ?4 L
mark:=true;
6 n7 g. N8 g8 {) n! |for i:=1 to n do
$ ?% z8 T6 W7 _& M- Z) a" pif (not mark) and (a[u,i]+d< d) then 3 r( w4 G5 r1 ~% G
begin
V5 o; E7 J1 C+ |d:=a[u,i]+d;
( d3 f2 O8 o8 I3 Y2 t# g0 Gpre:=u; % G) H& c. O& A% L* p
end; , S3 y) {- q* |, _
end; " O9 [* [% m# [1 B0 ~$ d/ s# ]
until u=0;
! l X) G& Q0 [8 ^end;
# k& `$ w$ j/ O: GD.计算图的传递闭包
9 ?# Y0 g) j) C g( ]/ ?( z" |Procedure Longlink; r; @' O* d0 L4 o: U, W
Var 1 {* \; X5 ?6 `5 j
T:array[1..maxn,1..maxn] of boolean;
# @3 W1 c5 W0 X9 P1 V1 ~% VBegin * c5 V* ^3 U6 |
Fillchar(t,sizeof(t),false); g8 Y6 f7 V( V! l" K, G
For k:=1 to n do ( Y3 @1 ], t% k6 d8 R9 o+ y
For I:=1 to n do
' C7 f1 `( G' h# h, ~; }. ?For j:=1 to n do
C& r$ j8 K1 a2 _' \ B4 m, bT[I,j]:=t[I,j] or (t[I,k] and t[k,j]);
6 `; R4 v* M6 N5 REnd;
l; |! H! W0 d
2 i6 \: H& ]6 K |
zan
|