- 在线时间
- 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.数论算法
% G5 I( F& S& {' ?- r1 h* g求两数的最大公约数
8 _& N5 o) f' q! F2 a) f6 o6 @function gcd(a,b:integer):integer;
7 a+ }( W; m3 C Ebegin / M" i: g. M7 b
if b=0 then gcd:=a
2 g& W% ^% Z) I' ]4 ]else gcd:=gcd (b,a mod b); ) ^0 Q& F2 _8 _
end ; ( @% _: ^* I/ \7 n: ?4 d
; t$ Z! d$ {& a8 @. v% Q求两数的最小公倍数 ) x$ A M, V- W5 i/ x: ?
function lcm(a,b:integer):integer;
# e. N8 f1 T. l1 mbegin 6 M- W& I( ~% w$ q8 x
if a< b then swap(a,b); ( T$ I' ^ C) I: c3 e, _ C2 Z
lcm:=a;
" s8 e& m" x9 V% j6 O6 {while lcm mod b >0 do inc(lcm,a); * U8 \+ }+ [# c5 M$ n
end;
( n8 [( E8 f/ [6 [7 s" j( U( k; p) n g
素数的求法 9 f) R- [ f* Z3 y/ B* C8 N
A.小范围内判断一个数是否为质数: - x! H" L4 [( W6 c2 x
function prime (n: integer): Boolean;
+ c2 D. M3 K/ `; kvar I: integer; / _2 }1 }! \6 S
begin & G* g1 W/ Z" C; b3 K- M
for I:=2 to trunc(sqrt(n)) do
$ @7 C% Z. V* a) D4 x" N1 r hif n mod I=0 then
1 D! h4 _' |, |begin , l) z" a7 K+ O4 m& u; e! m
prime:=false; exit; / L' R, d- O+ s$ `2 R% D! w
end; 8 Z# `8 w2 H0 j% M k# i. H
prime:=true;
0 o3 }) B5 s- F2 a7 qend;
2 u7 u. [4 A% O5 d. c+ c: g; E
B.判断longint范围内的数是否为素数(包含求50000以内的素数表): 3 F- [* v% d! k3 u$ |0 E6 x& v
procedure getprime; , b4 c O5 ]. }4 d3 E4 a
var
7 W" D7 `' `# ~7 \i,j:longint;
- Z- ~. r% j, S' u1 `9 Pp:array[1..50000] of boolean;
( m1 a1 x. `6 ^) v, Tbegin
* y. v7 o: r2 G5 i" i! e9 Wfillchar(p,sizeof(p),true);
5 q, Q% p& h) @0 x4 A# wp[1]:=false; 5 b2 C, S/ v& T8 w3 r+ U
i:=2; - k5 i% C' f; b' z" S
while i< 50000 do / c% `: K/ l' v/ N9 t- {
begin
$ g% |2 [( g# M/ wif p then * e2 p( b& Z) N6 X0 _$ S
begin : q! T) x5 M! R
j:=i*2;
2 \2 x% B. A- ?" p$ l. ?7 o& uwhile j< 50000 do + m' p- n( w7 t' F8 ^% y
begin 4 ]3 x ~( Z1 k/ Q# r/ A
p[j]:=false;
: M2 y' M6 e: g, O2 finc(j,i);
7 _0 q1 N0 j% u0 z9 j6 }, R" g9 nend;
- a) A, A$ G: k( Oend; , S! I- L) ]) c8 `( B7 a ?0 J! b! f
inc(i); ; g/ z: ?% v) o8 j; f$ n7 C
end; - L" D9 \, X# w7 Z% k' W, p3 s
l:=0;
9 m$ @0 k( V3 j: @% afor i:=1 to 50000 do
2 }/ w4 P! u. }& U+ W5 `, ?if p then
, L# |+ F; a6 @6 D0 y3 Bbegin 4 y+ m. ?5 w L3 U$ J
inc(l);& E$ J, }' L* e% T
pr[l]:=i; 5 M, ^5 K4 Z+ }+ w" Q$ J* K# u8 W/ o
end; i) M# O$ q ^/ D3 h2 m
end;{getprime} " _- C$ v! u* s. ]( U$ N
function prime(x:longint):integer;
j4 n1 \+ o, O. T! K8 avar i:integer;
& S, d A! F% |2 W" E# mbegin ( o" L) q% V# G8 q4 Y/ c7 n
prime:=false; , O4 u% C8 E4 g" L( T8 {% Q! Q
for i:=1 to l do ( j- {, ~% c+ ]8 {
if pr >=x then break . |- \& o) `& F% |
else if x mod pr=0 then exit;
5 t. [# M9 i# e) E) d0 sprime:=true; 0 z: G" g1 \1 p& v. p6 V
end;{prime} , @: }3 E4 Z4 h- B5 I5 \* g1 ]$ }
( g# G0 r# u+ J0 a; A6 w, n2.
" ^% Y6 m# ]0 z% w$ N: V, X% g+ i' Q9 m6 r* Y1 w5 T/ G/ i
3. 2 d9 j$ r* J! S; X' A+ J
& f3 |- z- T% h$ b0 y
4.求最小生成树
6 [0 _0 ]. z z4 yA.Prim算法: , w5 O! _; P! G! k) `# A2 n# a; T
procedure prim(v0:integer);
' ~, c0 p, J$ `" B6 xvar * x! Y q7 K5 A! ?, I/ t U5 I, x
lowcost,closest:array[1..maxn] of integer; 6 J+ ~1 Q: N% Q! s
i,j,k,min:integer;
/ t' f5 R! E0 Nbegin
2 F% a9 G& l8 N2 {/ vfor i:=1 to n do % i5 r, P2 V+ W
begin ' E- a/ ?' X8 w5 D) j
lowcost:=cost[v0,i]; 7 D! \6 C: v* z* N) z1 @
closest:=v0;
+ a7 u9 Y+ M6 N, |end; / q7 n8 A I) e, E3 o7 |+ S% K
for i:=1 to n-1 do ( r7 |0 o7 o6 f2 }- D
begin
1 c2 o9 V( q* F{寻找离生成树最近的未加入顶点k}
' o7 J$ C, ]; W- s# r0 c7 Lmin:=maxlongint;
, n; {; Z( R. U: Ofor j:=1 to n do
; T4 s) N+ H4 H/ Cif (lowcost[j]< min) and (lowcost[j]< >0) then
" }6 n8 f9 n8 T2 d$ x, U8 ybegin $ S8 z; |4 A2 i/ I0 ^
min:=lowcost[j]; % @1 v4 C% d4 z+ P
k:=j;
1 W. Z1 \( l" _* k; B1 m! r1 Pend;
" a6 v; M% f8 w) \3 ^lowcost[k]:=0; {将顶点k加入生成树} m. y$ U, \( C; q7 J8 j7 M7 ` h
{生成树中增加一条新的边k到closest[k]}
( s( K7 z; a8 W8 }3 R8 Z' D3 K- J{修正各点的lowcost和closest值} 5 L1 W$ X7 P$ s; a2 x" q
for j:=1 to n do
( J; b% i5 {6 Y: rif cost[k,j]< lwocost[j] then
9 u' y$ ]9 B0 w1 P: _begin
4 X3 Z0 A8 a/ @/ p' E4 zlowcost[j]:=cost[k,j]; 4 d: J7 y4 Y4 U- t# M& i
closest[j]:=k; 3 E3 a: G% v/ C* r
end; 4 K/ q2 n& V: F
end;
0 J# J' R, ~. j! Qend;{prim} ( B" [! @! k5 o+ _( r
B.Kruskal算法:(贪心)
: | s3 p7 y6 h8 }9 f2 d. X按权值递增顺序删去图中的边,若不形成回路则将此边加入最小生成树。
4 d+ z! A# X# Z3 \& wfunction find(v:integer):integer; {返回顶点v所在的集合} % k( Z g' S( p; ~
var i:integer;
" x; W; w; \; z( E, Y5 ebegin & K: ?2 o- W- G' }, K) c l2 [1 I
i:=1;
7 f {$ d. h. L6 Ywhile (i< =n) and (not v in vset) do inc(i);
) [' ^- f1 N/ p) m) W. hif i< =n then find:=i
' J t. X2 W m9 o% o8 kelse find:=0;
( o- f* |4 e% K. |end; % ^, i* ~% I' m" Y: c# C' N% R
procedure kruskal;
, ~; C0 C- d3 Cvar
+ ?$ \5 P' n h& F6 ktot,i,j:integer;
4 P: J) R- m$ |9 x9 tbegin ( {8 q% ?1 @3 @9 ^0 a+ E
for i:=1 to n do vset:=;{初始化定义n个集合,第I个集合包含一个元素I} 8 }9 ?" }% g4 G! W( N! V4 f
p:=n-1; q:=1; tot:=0; {p为尚待加入的边数,q为边集指针}
9 V F8 d5 Y4 w( @) W1 |7 hsort; 1 K; Y1 C' {# F: R1 ~
{对所有边按权值递增排序,存于e[I]中,e[I].v1与e[I].v2为边I所连接的两个顶点的序号,e[I].len为第I条边的长度}
( q0 f C7 a( S- mwhile p >0 do
+ }( g" K0 }) q! ^begin ) K4 \% D; I- U* R s6 T
i:=find(e[q].v1);j:=find(e[q].v2); ) @: j1 b% l0 @1 s9 r2 q4 a# z
if i< >j then . y8 W6 s3 ?2 U0 Y- {" S7 J
begin
' y x4 n6 v5 C( G" Dinc(tot,e[q].len);
3 w5 Z& z# G9 h2 z1 s( R) Dvset:=vset+vset[j];vset[j]:=[];
. \8 [! l3 R- }( o( _$ w7 idec(p); i8 z; O5 p2 B/ t, ~$ w3 ^ J' e, g
end; % F; @- `, L$ z2 O+ K9 I
inc(q); ) z8 O4 h; {3 Y7 V/ {$ e
end; 4 e) m+ x8 R6 }/ L2 x; V
writeln(tot); $ p/ n" m+ [4 f- C$ G
end;
# \6 h& h1 Z6 [7 X8 [ s1 P7 O6 }7 {* r; `
5.最短路径 : X" @6 V6 o u4 l. t
A.标号法求解单源点最短路径:
1 t( m" F4 _/ y' U! J7 j' |6 ?var 4 t$ o$ s7 f" e, q* p
a:array[1..maxn,1..maxn] of integer; . s* }# n: T1 |1 w
b:array[1..maxn] of integer; {b指顶点i到源点的最短路径}
. Y/ L4 I; z* Z! G! l& C2 qmark:array[1..maxn] of boolean;
: C, C! W4 T1 t# h* s1 v2 [3 Q4 y0 [7 V3 v& Q, p- H
procedure bhf; 4 j6 v2 `+ a9 y. ~1 b2 d% Z
var
* s' F& E8 K: V/ g1 o, Tbest,best_j:integer; & s5 {- [. \9 e' S, [0 ]
begin 3 E7 ^6 c: R% z6 H ]
fillchar(mark,sizeof(mark),false); . b+ a' \' w6 [" D S
mark[1]:=true; b[1]:=0;{1为源点}
3 M9 r3 R9 o V0 |% U5 urepeat
% X* H! o( d* g, `best:=0;
; l) ?1 N! w* u( S6 O4 bfor i:=1 to n do 7 V* F6 \! l! E% R) [' R9 _
If mark then {对每一个已计算出最短路径的点} 3 {! x8 U; Y( H; [
for j:=1 to n do
; v/ N5 }/ t" U; j$ _5 q" iif (not mark[j]) and (a[i,j] >0) then % }2 n. S0 z8 w& S' a' x, |
if (best=0) or (b+a[i,j]< best) then
% U8 H$ U4 l/ D; _/ ]3 G9 Qbegin ' W* b5 t: L3 b) T
best:=b+a[i,j]; best_j:=j; t! M: c" S" H, z
end; / E v+ k$ X) {' V) o) p
if best >0 then
$ c; f5 p c5 U. pbegin
0 }% k* V# f% x3 A$ Wb[best_j]:=best;mark[best_j]:=true; / P* x+ H7 h! [; G
end;
- ^* v! P e& `- s8 @ k" |. [; w( vuntil best=0;
7 Q0 [ S8 u) D& zend;{bhf} 1 o2 q5 F. [! F* A5 I9 t
% l, c/ z+ b6 k0 q( K7 g6 g5 s
B.Floyed算法求解所有顶点对之间的最短路径: ) _" e* a) C8 z0 z, w. D
procedure floyed; 5 E: m. H- @+ t$ E7 d# O
begin
~- |# x3 \7 rfor I:=1 to n do * k( Y' q; l7 N$ Y8 i' c
for j:=1 to n do
7 o7 {9 u. I3 W+ uif a[I,j] >0 then p[I,j]:=I else p[I,j]:=0;
+ n% _6 f2 R9 @{p[I,j]表示I到j的最短路径上j的前驱结点} % F" x" J7 X5 f E9 u
for k:=1 to n do {枚举中间结点}
% W) Z! ]( K2 u% n2 {2 i5 kfor i:=1 to n do 2 A2 H9 h! e3 Z
for j:=1 to n do 4 f, V: W2 ^+ h( j9 x
if a[i,k]+a[j,k]< a[i,j] then 3 b' V8 i) X9 ^
begin * R7 z, ^4 `/ w& o; K( F5 E% y
a[i,j]:=a[i,k]+a[k,j]; 1 |; c& Y/ T; G4 C
p[I,j]:=p[k,j]; 1 f9 K) p* Q9 C3 ?& x% {- @' [
end;
, [5 O# P& t! J; g3 g* i4 Oend;
" E0 L8 a3 a- i( p, H7 u" k- FC. Dijkstra 算法:
6 V( J* C3 o+ G% V类似标号法,本质为贪心算法。 " W/ L1 B$ q# j1 q) Y) M
var ! |+ U- Z- v- b0 H; L1 u+ i
a:array[1..maxn,1..maxn] of integer;
8 ^* P6 H/ l. j4 Pb,pre:array[1..maxn] of integer; {pre指最短路径上I的前驱结点}
. R2 x9 g3 }) D, }9 s% omark:array[1..maxn] of boolean;
" J8 ]% u1 `+ \& E) Iprocedure dijkstra(v0:integer);
* E, q9 L8 }$ S/ c6 obegin
7 X& S$ i: F& U7 R+ Q& l6 C: C0 Ifillchar(mark,sizeof(mark),false);
T5 ^. v$ }$ G2 L, R/ a3 h W, tfor i:=1 to n do " G6 L% v% F- n* m2 [ i6 U6 }
begin
I d8 A- C; O3 |0 o7 F" {d:=a[v0,i]; : w7 K+ r$ \) n. o1 z
if d< >0 then pre:=v0 else pre:=0;
" [. @# V7 b- f7 @+ \, O7 hend;
8 s ^- z" i+ S" V- |2 ]0 ^4 bmark[v0]:=true; 4 S; m- n0 k" a5 ~7 r9 E
repeat {每循环一次加入一个离1集合最近的结点并调整其他结点的参数} 3 N% K! |. n4 v) @9 O
min:=maxint; u:=0; {u记录离1集合最近的结点} ' d7 ]. k9 f3 m
for i:=1 to n do
& B) d' \4 g% {+ U, o7 J' \if (not mark) and (d< min) then ( i% W# T" ?8 ` Y# |* ]5 ^
begin , p8 O( x* `/ {- n$ c2 U
u:=i; min:=d;
0 v V0 F0 \5 I7 R: }5 _; |end; . z! h! I: j5 q' X3 ]
if u< >0 then ! G; W/ t/ o; Y6 c
begin + X* |5 P2 P: V& g' {
mark:=true; 3 Z2 D. d4 X2 ^8 f9 d1 d
for i:=1 to n do + \8 Q1 d5 @ k, e1 \
if (not mark) and (a[u,i]+d< d) then
8 K1 N4 Z/ R3 _! O( X; kbegin
; [ P- V6 K; u8 a' ^5 Zd:=a[u,i]+d;
5 U' ~$ Q) [7 {" \8 j2 P+ Rpre:=u; ; [; P" r5 l' `4 E8 E8 O: g2 p
end; 7 T- x. q/ c" j3 t
end;
$ t C* L0 S; e4 `2 v. [" \* Vuntil u=0; 9 b; T8 V4 M1 F& z6 R* ^6 H
end;
0 m! ]( v7 J5 V4 b5 ?D.计算图的传递闭包 * v0 w4 w) k2 A8 E
Procedure Longlink; 3 W# r( k5 `2 r6 u" V6 F
Var 7 z. S+ T1 C$ \* U9 f/ D# Y- e) |
T:array[1..maxn,1..maxn] of boolean; ) u3 i* A/ v' t
Begin % d2 g5 A% l: _/ e, C. l
Fillchar(t,sizeof(t),false);
4 @& l2 @( o( P- |7 e0 e% OFor k:=1 to n do
' `# o" i% r4 P6 |; gFor I:=1 to n do - @; x# J; R* ^ V. a' J |
For j:=1 to n do
. q' B) z. q' H; P* @6 X. c% {T[I,j]:=t[I,j] or (t[I,k] and t[k,j]);
/ N9 }5 ]! m8 K0 z4 P. z' p* c) K4 XEnd;) t7 Q$ D! z% }4 q/ H# f
5 Y) p7 o6 n+ b0 ?. }/ v
|
zan
|