- 在线时间
- 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.数论算法
4 s& h( p% H+ k5 T求两数的最大公约数
# }7 k; X+ |/ o' Z" u% Ffunction gcd(a,b:integer):integer;
. R; K4 l, T0 Nbegin 0 q1 |0 o( x' j$ z- \* `5 c
if b=0 then gcd:=a
& H3 ~& k( n7 zelse gcd:=gcd (b,a mod b); |! o- k; Z6 ?7 w4 j
end ;
N3 D" C; g+ r" X% H
' ^1 E" v3 t" c3 F求两数的最小公倍数 5 `$ n$ R% Z; y3 J* {% U: B
function lcm(a,b:integer):integer; 8 ?! A; ~& v6 L2 i9 L6 O; E
begin 3 D! S/ Z2 \ k5 W
if a< b then swap(a,b);
7 `! t/ X6 D4 X+ m; ^1 j1 klcm:=a;
4 G/ @* _0 ?6 a, Xwhile lcm mod b >0 do inc(lcm,a); . Y1 L! O2 ]. w: j d1 G2 ~
end;
8 @6 h9 `+ i* q3 {# Y; M6 q5 I. h0 l
素数的求法
1 J7 n ]' k; C# W' \A.小范围内判断一个数是否为质数:
5 e8 U3 r' }% Q) }) S6 l; ?8 W$ Qfunction prime (n: integer): Boolean; " e' ~8 Z/ v% D1 R V+ V) P; F) t
var I: integer;
# }" L; F) Y- g1 t+ E2 T: mbegin
1 V$ v' s6 I: M) m1 p0 c4 n$ ofor I:=2 to trunc(sqrt(n)) do ) i! }& I9 ^+ o/ ~3 W
if n mod I=0 then
N' x O7 M* y2 zbegin , U5 j2 [ K' ~* N7 V: y
prime:=false; exit; # R/ j% g, T9 k @# x& y: g
end;
; W# I/ {3 B! u" |. k* d! q/ fprime:=true;
, J4 F V( C/ c# m( n8 T- Zend; ( D/ v4 l, H( I4 c
. s. c$ q& e9 j/ e4 lB.判断longint范围内的数是否为素数(包含求50000以内的素数表):
8 F3 o9 d) A" @/ h" k9 l8 w3 m& K" Hprocedure getprime;
1 U* K$ O: G1 W t- M$ C0 w" w$ yvar
: I& k" E0 c* {) d3 Zi,j:longint; 7 c$ A c& m& m# D3 S6 a7 [' n- \
p:array[1..50000] of boolean; % K; _5 o0 {0 t* |. W% {2 t8 E
begin
$ J! \$ R$ i5 P- xfillchar(p,sizeof(p),true); 3 y+ ^3 _6 H) S" x9 \* d, E
p[1]:=false;
* V$ R# L! x9 r; H& {3 Ki:=2;
$ D" s( y% i( ]while i< 50000 do 6 d( \: {( v0 Y
begin
) D+ \7 |$ _' Y0 M) eif p then 9 L* m4 c1 l0 h& b" U/ r
begin
2 c5 y/ J/ d* _0 T$ f# j2 R9 B+ F; bj:=i*2; . V s/ |" I8 S7 p# a- P* C
while j< 50000 do 4 f( n- o- B- E4 |( Z# f7 j( v e
begin & e! n' I1 q0 |3 k2 U& H
p[j]:=false; 8 D6 r8 o) I; {# K1 \( n
inc(j,i);
: I- j/ I6 [ G" A7 S/ jend;
6 g9 i# C7 C; s: K! H, rend; # u% H6 m5 T; s' m
inc(i);
5 q0 \. }+ T2 @end; - Z$ ~# d* v3 m K
l:=0;
$ ~* H; e7 m+ k7 t3 Mfor i:=1 to 50000 do
8 m0 L( ~1 |) n. Z: N0 cif p then
; W$ d% q5 ]3 Y4 Ybegin
) _3 u+ ~4 r5 C+ x3 v' s- |inc(l);7 c* n; K. c; \6 L0 @4 ]
pr[l]:=i; $ g- z& j! _/ ^+ P$ `
end;
8 Y( r" I5 \, C7 n) Yend;{getprime} 6 D% a6 y* G" O2 ~$ n
function prime(x:longint):integer;
a% r- x( q- }2 p& Y" Yvar i:integer;
' I# x$ J1 V1 f. l2 e4 e+ t3 P/ ?begin 8 H4 i; m. B. Z* x) t) u2 M
prime:=false; 6 `# Y. s( E/ x0 o ~. U' p
for i:=1 to l do
$ [2 W2 C1 C, u' dif pr >=x then break
( t* L. O7 U' W7 _1 x& Aelse if x mod pr=0 then exit; ; S9 Q) b. X+ g+ _( K" W" n
prime:=true; ; |% W; H2 l( a. J6 z
end;{prime} ! ?( e6 H4 P) N2 q* A% L0 M6 G
9 H: ]7 f1 ~0 t. b4 m& Y2 ^, D, O2 t
2.
3 L. }$ A, _# i5 }* N
: n" m+ S5 x! X3.
- P0 D6 \& i' Z$ G) h0 O, `! C2 t5 X0 C) A
4.求最小生成树
# j* R: J& I" X5 ^+ a* gA.Prim算法:
% G( S ~. q$ t! Z" |/ O# C* wprocedure prim(v0:integer); $ d) V+ T- |3 L
var . T/ N- l0 f7 D0 \8 |! P8 |
lowcost,closest:array[1..maxn] of integer; ; p/ E6 p6 R; L0 m+ ]$ @- R
i,j,k,min:integer;
" k" C8 J% Y% @3 }! V& P2 }8 Ebegin
9 l& \" Y6 o. I1 d% Z! yfor i:=1 to n do * n' d& _$ l, Q ]- a5 X
begin
* l3 o2 p3 q% G: f# tlowcost:=cost[v0,i];
, Y7 q- E. t" o- h+ kclosest:=v0; 7 w$ V+ H2 k( ]/ x5 T. ?7 i
end;
9 Y& w2 K6 s; w0 A" Kfor i:=1 to n-1 do 1 ~, w% h4 ` K7 B) I0 [! L! N
begin
2 x3 B/ f! B. O# v$ s{寻找离生成树最近的未加入顶点k} + r( A! y: i* a
min:=maxlongint; * w, b& d# |3 D7 s5 ]
for j:=1 to n do
5 \1 n" F* g& E9 w- S4 |1 gif (lowcost[j]< min) and (lowcost[j]< >0) then * q8 K) w6 ~# ~1 @8 E) A& ~
begin . q6 K z, D+ W4 E2 H4 F% @
min:=lowcost[j];
$ B, W4 _1 x8 [- U; v# K6 Fk:=j; 3 y3 S7 I. R) H- p) ~5 e3 ^
end;
0 P0 i% g$ c1 ^lowcost[k]:=0; {将顶点k加入生成树}
8 N4 H8 b/ E/ t3 d8 M{生成树中增加一条新的边k到closest[k]}
; q' y& m1 X# {0 b x{修正各点的lowcost和closest值} - {( I; U; x( X
for j:=1 to n do
) o/ K9 K. T/ v. E: \if cost[k,j]< lwocost[j] then + e5 E. W2 o7 F. g) |! u' y
begin
- q- n& W0 ~4 Z4 @lowcost[j]:=cost[k,j];
& c7 S8 h7 ]* n% N& T. d* zclosest[j]:=k;
- I! d5 X) D( o2 U2 n6 M8 Kend;
+ t. z3 r. k" ~' ]) ]! Cend; 3 o& G! Q* S& t1 M* |1 k
end;{prim}
( _7 L/ B0 P4 b; [8 \B.Kruskal算法:(贪心)
- S% U$ I: y; O/ e1 j, F按权值递增顺序删去图中的边,若不形成回路则将此边加入最小生成树。
; `6 B9 J. u$ N' lfunction find(v:integer):integer; {返回顶点v所在的集合} - U; H! y2 r9 M$ E. A1 w
var i:integer; 4 C* y6 _! `7 w' y$ F9 e% d
begin - S& {+ d& @9 Y0 N/ {! D+ r
i:=1; ! E2 g. H$ G, r5 D0 y
while (i< =n) and (not v in vset) do inc(i);
& U: {" e% M6 `: Aif i< =n then find:=i
( I. C. s$ R5 Y, z/ \else find:=0; - v5 r5 R( a: m; N4 h
end; ) d- ^9 b' b4 }2 G! f
procedure kruskal; + l8 [4 _& ^, m
var
/ R8 K# Y3 R" i2 [2 x1 Ltot,i,j:integer;
" y: \$ E( w; \8 i2 ?begin
: x! k4 m" Q- L5 tfor i:=1 to n do vset:=;{初始化定义n个集合,第I个集合包含一个元素I}
4 f8 }% l( m4 L$ b# d( S- sp:=n-1; q:=1; tot:=0; {p为尚待加入的边数,q为边集指针} 1 L' h o& M! f/ F
sort; 7 Z- h/ W) L" k3 p9 r: N
{对所有边按权值递增排序,存于e[I]中,e[I].v1与e[I].v2为边I所连接的两个顶点的序号,e[I].len为第I条边的长度} ' g6 W" Z2 v% O: Q" c. }
while p >0 do
: X8 I2 h' k7 m* \begin
3 {% h2 g! }5 `0 X* xi:=find(e[q].v1);j:=find(e[q].v2); & e4 t; v) J8 r' y. S
if i< >j then / J4 S9 h& A: X
begin + E* J, D( c2 D2 M& X3 z! G4 \
inc(tot,e[q].len);
" W; H% J, a4 P6 yvset:=vset+vset[j];vset[j]:=[]; * D# L j) x+ M: Z4 J( s7 o
dec(p); 6 ?# I0 n& P2 m: F4 S' j
end; 3 M5 o) d8 W1 m5 G: V
inc(q); / M Y# S: H' D/ h5 `& U( ]1 i% t
end;
* u" S4 j0 @7 f1 @writeln(tot);
" B+ S; I3 S3 o; G; I: H L4 yend; * b( Q" e+ o3 Q3 g8 {. G
. n2 ^' b+ S- i& Y5.最短路径 ' f3 {4 C- Q9 ~7 I, @$ d
A.标号法求解单源点最短路径: " V: z5 ~* C7 _- T, g5 M
var
: ~% p) T* @1 P p" r) H, Pa:array[1..maxn,1..maxn] of integer; {+ o7 }, W0 U7 x9 l A% b, n4 L
b:array[1..maxn] of integer; {b指顶点i到源点的最短路径} 5 q9 [0 A. Y/ @
mark:array[1..maxn] of boolean; ! U+ R: p, w0 S
$ i/ _* x( s' X" M8 t
procedure bhf; + g% P' ]. J/ Z L4 G' f& q
var # p; y5 Z" k' b5 S
best,best_j:integer;
! b7 j7 U9 b5 t% w0 lbegin . }( |, \/ l# C" K
fillchar(mark,sizeof(mark),false);
3 I/ {7 T4 `+ B( F! K: Bmark[1]:=true; b[1]:=0;{1为源点}
% j+ S2 W( G6 Q( K8 rrepeat ' D% g- N, r- j+ B. D
best:=0; b& K/ k% Z- c/ Z
for i:=1 to n do . Q9 \; ]" H: ?+ J. p3 q: r
If mark then {对每一个已计算出最短路径的点}
5 F( w; q2 T5 q5 ^9 ]. b0 R. mfor j:=1 to n do
- v6 i1 _9 ~/ a( |$ ]: K- nif (not mark[j]) and (a[i,j] >0) then
6 X1 ?! d1 ^+ m2 I4 H3 Mif (best=0) or (b+a[i,j]< best) then 5 t3 W2 i1 i3 _$ `: N; }
begin
5 k8 J- @* ?" T3 I. Wbest:=b+a[i,j]; best_j:=j;
% {( ]6 I% I6 j4 M/ bend; * w0 t( ` Q" z1 q3 r
if best >0 then
0 B) ^' e# ^* Nbegin / C, ~% D4 D ~ m' b& Q
b[best_j]:=best;mark[best_j]:=true;
# q6 j, S; h6 F# R; E% ^' G& n" Q& send;
0 H, N P" M: ?% P3 Wuntil best=0;
; S/ [5 w' j" g5 P6 G& U. Zend;{bhf} 2 F. ~5 U" [/ H7 G
) m2 G6 _- X, @% HB.Floyed算法求解所有顶点对之间的最短路径: - t' Y: ?$ _- a3 K- A4 Z) @ `. P
procedure floyed;
, ?& I$ W! x* [. e: _6 `: a" @; lbegin
8 o) z; H. Z5 O3 ]! Ufor I:=1 to n do
+ Q3 i' Q; R8 z, G# efor j:=1 to n do t) O( m2 i5 ^; r1 z% v# w
if a[I,j] >0 then p[I,j]:=I else p[I,j]:=0; : g6 S/ G7 P# v0 n
{p[I,j]表示I到j的最短路径上j的前驱结点}
, B4 y5 i% w& D' z e2 b# L: \for k:=1 to n do {枚举中间结点}
2 }6 H# b) A2 u( _. X g9 V) jfor i:=1 to n do
: n) G/ B$ {( m; K ]3 m/ Ufor j:=1 to n do 3 V) R4 Q; d4 u# c M% `
if a[i,k]+a[j,k]< a[i,j] then
( O0 c! X; a* S' I" Z) Dbegin
5 C& {. x5 F0 n5 _3 s6 qa[i,j]:=a[i,k]+a[k,j];
: ~9 i" u7 ~5 W. t- u) cp[I,j]:=p[k,j]; 6 P! r' d. X1 M- o- r
end;
: o; z0 K A | U" w; K/ ^9 fend; 1 J" _) i+ ~% B- f
C. Dijkstra 算法: 6 F. k* q8 ^4 p0 B/ f% B
类似标号法,本质为贪心算法。 - u& h6 G) r# s P8 h' v6 `5 I5 f! v
var % E2 z: f+ y% U. j. u
a:array[1..maxn,1..maxn] of integer;
; {8 D% ~% r2 y9 a) M, |$ k3 |b,pre:array[1..maxn] of integer; {pre指最短路径上I的前驱结点} & a% c, _( ]* d! F7 k) v% I
mark:array[1..maxn] of boolean; " F/ X8 D! ^8 W/ H" S& p# D/ J, b
procedure dijkstra(v0:integer); ?9 e# u! u/ Q5 X+ l( a$ M
begin
, R$ M, f7 c. K9 jfillchar(mark,sizeof(mark),false);
( K! c$ Q/ i7 y! X' o( a3 l7 T/ tfor i:=1 to n do
- i: k$ r6 _% B- e# r( G' ~begin 2 ?! _3 `5 q0 N! j( @ J& h
d:=a[v0,i];
5 P0 x8 S) A- C: k( T, Jif d< >0 then pre:=v0 else pre:=0;
. Y; t) a4 c# ?/ Qend; 2 S w+ h8 Y1 u# X ]% S# O5 N7 P9 [
mark[v0]:=true; ) i0 S5 ~" H+ W" x4 o, I$ x
repeat {每循环一次加入一个离1集合最近的结点并调整其他结点的参数} + l$ }1 X4 C) W( E+ ]+ ^
min:=maxint; u:=0; {u记录离1集合最近的结点} 5 _& _! }/ o6 `4 x
for i:=1 to n do
8 A$ O, P7 S1 ^3 q, vif (not mark) and (d< min) then
$ h, t3 x# s$ ^* o* Q& ^8 Bbegin , C% H/ Y) A9 C' B
u:=i; min:=d; # c- H3 V0 N, d
end;
9 y& |% H) B8 i$ y; ~4 \if u< >0 then . h; d3 [ C' W4 L" ` ]- |
begin
7 [% \( a+ f% J4 O+ wmark:=true; 1 f# X0 |4 E) l3 ~! ?
for i:=1 to n do
! S+ `/ a2 K# \9 x; cif (not mark) and (a[u,i]+d< d) then
' ~! B: z" U3 Q5 Ubegin & U5 [- I! g; {9 ?0 E
d:=a[u,i]+d;
1 |5 a7 V! n6 S+ n( Tpre:=u;
" _1 i# M. R( \end; $ t9 d! k8 H! T
end;
7 c/ Q8 ~$ }+ i8 p8 }" m2 K# Tuntil u=0;
, H2 T# {+ {8 K( wend; * Z8 `& ?. S. _
D.计算图的传递闭包 : _0 N* n0 Z3 ?# c1 D
Procedure Longlink;
& q0 d% C- J; B. y. FVar & ]1 U D! I& v- C
T:array[1..maxn,1..maxn] of boolean;
1 G) F9 F6 P4 j; g7 d/ `Begin
7 u" B) e! Q+ Y: ~& mFillchar(t,sizeof(t),false); 8 @1 M! h* u1 E( X! i: R3 k
For k:=1 to n do
/ G1 }, a5 X/ A) j) A* CFor I:=1 to n do r, A& K" p- ?, p
For j:=1 to n do
9 f" O) [. |) B( iT[I,j]:=t[I,j] or (t[I,k] and t[k,j]);
2 ^ F x/ l6 C; m: sEnd;/ x/ f; g- j J6 o
( o2 ^5 y4 x6 m! d
|
zan
|