- 在线时间
- 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.数论算法
: v; N+ l1 \) M$ O6 l求两数的最大公约数
' N) S- U: G5 l) U, Zfunction gcd(a,b:integer):integer; $ f$ u% p2 C# w$ ]+ U
begin
( F* l F, |1 E/ D; ^if b=0 then gcd:=a
7 j; `. Z( x. O9 {5 Welse gcd:=gcd (b,a mod b);
2 [. p7 k4 ^5 Z0 xend ;
9 y/ ~4 A/ t1 }2 P2 h
! N9 q% x: X [+ A求两数的最小公倍数 - j8 G s, }1 O/ u$ _
function lcm(a,b:integer):integer;
" G, T* Z5 `1 b5 Z. Ibegin
( p% `" ?0 p& I" rif a< b then swap(a,b); & F) e% x* @# H/ v/ R3 {
lcm:=a; - w. B7 l$ ]/ V% w
while lcm mod b >0 do inc(lcm,a);
" i$ t4 }# q- Qend;
7 s8 G/ @6 [' D; J- F7 x9 H0 H: P- E6 ^) f# ^( W4 @( b$ h
素数的求法
p4 O* v. L/ x; N; d' HA.小范围内判断一个数是否为质数:
& f+ t0 h/ V0 ?6 ~# }function prime (n: integer): Boolean; * @$ [) _' r o7 m8 k
var I: integer;
1 @6 T2 \9 a7 @ q# {begin , Z' z# Q$ Y K) G7 @# U- \; M
for I:=2 to trunc(sqrt(n)) do
7 J; Z$ E: r6 q5 Q7 V4 v6 ]if n mod I=0 then
5 q+ ]; k! F* T5 M7 G0 a$ I# d* Wbegin
& `, x' H+ y+ l& \7 q2 @1 T. _' aprime:=false; exit; 3 h1 b ^& P9 S& F. n
end;
3 ^: X8 L; ^# I& i& |prime:=true; " o4 j& e) n- J. X# {6 T- y- w
end;
1 s% y7 t: \5 B. {
! B: I+ _/ o0 B: T" r8 Z9 h7 P" m) AB.判断longint范围内的数是否为素数(包含求50000以内的素数表): * J/ N0 I, B+ ` I
procedure getprime;
( r7 }" f9 p6 w) h; W: Z5 x& c- fvar
/ [' l4 ?4 J+ |; A) @7 a+ V2 Wi,j:longint;
& E# C2 y$ D9 D7 {% h0 P2 p/ F) Y- Sp:array[1..50000] of boolean; 6 T/ S& _& [& \8 K: {' ^) ~( [
begin ) c2 m$ e+ c8 D f
fillchar(p,sizeof(p),true); - q* Y7 a: _0 Y6 ~& Z+ W6 x. r
p[1]:=false;
0 | |% S0 d6 x) ~+ N4 v# K0 C9 ^i:=2; 7 y9 l/ v7 |$ B1 d8 Q- x1 _
while i< 50000 do 5 q0 r% \9 {& ~% c4 ^4 f; e
begin - F$ h) k, U, D3 g
if p then ; N# Y- n6 b+ u f7 L& p% ?8 ?5 s6 p3 \
begin
. M* k) t- _' ^5 V5 M4 Y) Xj:=i*2;
, k* ?* X+ M) ]$ B. e5 n% B: ?while j< 50000 do
# v- V. @* ]8 W- k: X0 }begin
# }7 ^6 }& r" a4 O& i# [p[j]:=false; 3 X8 J2 t0 D9 q+ D* B# \/ j9 U% f) D) R
inc(j,i); ' S/ c0 J+ j2 H: C; p" M; ?' {* u, P
end; 4 N" v! J9 v* o* W" y& d+ h) c
end; ' j9 B4 i- W9 Q* Y$ R& J$ _
inc(i);
9 Z( u* R0 n) x8 ~% Y2 R7 jend;
, r6 A3 M. C+ \6 a$ S9 G4 Xl:=0;
6 ^! c A& G; `& r* e! v: Tfor i:=1 to 50000 do
% f) b! h# `7 [! O$ U* p! fif p then - z: B/ a. F3 I) H9 b6 T1 l
begin * s6 u- X) W; }# C. L3 Q6 w4 W
inc(l);/ g; M5 @+ l+ p! a3 y, P; S5 _
pr[l]:=i; + C) r/ y9 N6 I r0 Q
end; 4 O# x: [' S( b4 H |* b
end;{getprime} % L) d6 }' ?6 a# F
function prime(x:longint):integer; 0 P/ m( A2 R. m |! n4 ]
var i:integer;
1 B; i& Z3 y. D3 U1 ^& S- U) s3 Mbegin * g6 r. i# w: J* b& X
prime:=false; . R; r8 M1 D& U/ [- T
for i:=1 to l do ! l- ~! p+ W( X
if pr >=x then break
% x# W, G; W9 ^* B$ pelse if x mod pr=0 then exit; 0 ]& F' {; Q% E
prime:=true;
, R) [* l. i3 Lend;{prime} # U% j; @8 c8 A0 H' ?, d
' |+ H" w6 F4 s# R; O
2. & W" c, O4 I9 c1 x
( ^4 h$ ?' f% D. }8 j& H1 L
3.
) r- L. R3 _$ Q1 o) o5 h6 v$ R) w9 v, f* ?( Y
4.求最小生成树 ! A+ ?2 U" b5 W9 _: H
A.Prim算法: 6 |& }' A0 L/ Z6 i$ e- x2 i
procedure prim(v0:integer);
+ ~9 k7 Y& B5 L5 D) L; ~var
% S7 z. p* u7 h1 `. j2 qlowcost,closest:array[1..maxn] of integer;
- y! o# u5 l5 W" {i,j,k,min:integer; 5 L9 b, W. M( x( w
begin ' H4 t! v: ?9 n1 t" k
for i:=1 to n do
- G9 P9 a7 a$ K- F9 ~& Obegin ( o2 l x/ k2 j' p
lowcost:=cost[v0,i];
; V( e( B* V3 e5 j/ Eclosest:=v0;
: Q3 X$ C7 B [ I: Vend;
# {2 N4 j# r" a- D- k1 s3 z7 f. ]# ]for i:=1 to n-1 do
: Q0 k* D6 C6 {7 I m4 }begin 8 R& U& {* B( Z* O3 L" b n
{寻找离生成树最近的未加入顶点k} ( \0 D. p$ m0 v C5 D5 @# z3 t, H/ g
min:=maxlongint; . D, ]+ o+ e6 O/ M
for j:=1 to n do
5 t' p& B* a& w* cif (lowcost[j]< min) and (lowcost[j]< >0) then ; p% _$ a* y, L& d
begin : ^. a5 q/ k2 t; v5 ]- x
min:=lowcost[j];
6 h; J1 }" R8 O/ M7 }) {0 Yk:=j; ' e7 S4 R: {2 i" v0 _
end; 9 u9 B; Q6 R, F; G$ V
lowcost[k]:=0; {将顶点k加入生成树}
( z3 r$ J( ?1 Y* k/ ~$ }* m& W{生成树中增加一条新的边k到closest[k]}
7 V6 ^8 I9 S& e+ b0 x; A2 ]; k{修正各点的lowcost和closest值} 6 s! M' k7 J9 b/ o& G6 z. S4 W' D _* m
for j:=1 to n do
. V0 A6 m& X% j+ x, Eif cost[k,j]< lwocost[j] then " p! ?' N- m/ b2 V4 N4 s/ a, v
begin
6 X- D; l$ s, q- c- c( ilowcost[j]:=cost[k,j]; 8 M+ K6 Z. \9 n- V0 ]
closest[j]:=k; - a# B* g5 Z4 |/ H
end;
" d9 y1 P; y- j8 \end;
% N6 X) e9 `7 G& K* {end;{prim}
9 |9 S3 [6 Y6 e9 r7 UB.Kruskal算法:(贪心) ! A% P' `$ r- }
按权值递增顺序删去图中的边,若不形成回路则将此边加入最小生成树。 ], \1 Z+ q7 J" X* A9 e
function find(v:integer):integer; {返回顶点v所在的集合} - s$ j' s+ B4 l4 S$ S1 o
var i:integer;
) F( X& ?" J0 O! {# b N& t+ K: wbegin 0 n1 S% Y& s" b3 J
i:=1; ) N/ M5 q/ Z5 h
while (i< =n) and (not v in vset) do inc(i); 2 v! {% e9 b2 T& _
if i< =n then find:=i 1 }! `( y# j; A( }
else find:=0;
( s { L ?# G# `; J* f# aend; " C& s; y0 y0 w' H, U6 Q" w0 E
procedure kruskal; - G. m$ j0 I3 a" a: G: Q
var
7 q% u2 E8 Z" N; L5 ?tot,i,j:integer; ; H; L0 \) Z4 `2 a, b Y
begin
# k+ d4 _! M5 g- W( | E3 B4 m2 Qfor i:=1 to n do vset:=;{初始化定义n个集合,第I个集合包含一个元素I} , W9 _3 h8 w8 F
p:=n-1; q:=1; tot:=0; {p为尚待加入的边数,q为边集指针}
/ z8 y6 z8 f; o) h- Ssort; 9 x: B7 _2 c; _8 l! T; R
{对所有边按权值递增排序,存于e[I]中,e[I].v1与e[I].v2为边I所连接的两个顶点的序号,e[I].len为第I条边的长度} ) Q4 h B- I5 ^% l6 a2 a: g
while p >0 do
0 W* S6 `' v0 J/ }0 zbegin
1 a, s' e& o# N& r2 li:=find(e[q].v1);j:=find(e[q].v2); 4 ]8 P* T) E/ f# {4 N( T7 n! I
if i< >j then # W6 l' d) S, C
begin
) D% ?+ ]; O" o! s0 U, u6 R! jinc(tot,e[q].len); * D3 S( ^; B% |4 s, y5 `
vset:=vset+vset[j];vset[j]:=[]; 9 k/ J7 l ]* D7 M- y4 @
dec(p); 7 F5 D7 l5 N+ y. D8 |
end;
! O( i4 ?9 e( I3 k jinc(q); + b% N# C L. W1 Q5 e! W
end; ' b) z/ X/ r I
writeln(tot); . ?/ m/ j6 h6 J$ R2 h s
end;
2 u. h5 j& \9 s5 L5 s. f- Z3 b
$ G0 r$ F* i9 J' [& |" l& |. Z5.最短路径 " {0 `) w, L6 Y4 Z4 f! U
A.标号法求解单源点最短路径:
" M/ d/ M' C! ?# J# hvar
/ L9 Y% N$ j3 V: c; T* D. J/ W; va:array[1..maxn,1..maxn] of integer;
( H0 B* O" P; S: f) U5 ob:array[1..maxn] of integer; {b指顶点i到源点的最短路径} & o7 o% v' o" t' B& H
mark:array[1..maxn] of boolean;
) I0 l) Z, o* O$ G3 I- Z: p* k- u* w2 _) ~+ g- H
procedure bhf;
& Y% C a4 L2 _5 J R" z% evar 6 g: F0 ]& }* H n4 `2 s& B
best,best_j:integer; + p; y$ p6 \1 C) T
begin ) P, u4 g5 F1 U
fillchar(mark,sizeof(mark),false);
7 Y# Q' y, V0 V+ q4 z7 Q/ gmark[1]:=true; b[1]:=0;{1为源点} " Y; C$ E! }4 t; t7 G
repeat ' m7 O$ F5 Z0 B. q" f
best:=0; " b( |2 c6 K8 S7 [$ D: h
for i:=1 to n do 6 Q% ^, C$ M) P3 S5 G
If mark then {对每一个已计算出最短路径的点}
/ u' l, M3 x5 ufor j:=1 to n do
3 H- Z& ]1 j- w6 O Fif (not mark[j]) and (a[i,j] >0) then 4 i4 @) D& b/ q
if (best=0) or (b+a[i,j]< best) then 0 x/ D# }! |0 x. J
begin " I; Y% W; p) t8 x/ {
best:=b+a[i,j]; best_j:=j;
0 _' r3 e: L! r7 Z6 Y4 Iend; ) [9 \, \9 N3 s
if best >0 then
9 |. a: [: f8 y" N* _" Gbegin
' C; e. ~3 l% g/ t/ cb[best_j]:=best;mark[best_j]:=true; R' X" U7 M) ]. `
end;
) C) I, w4 @$ H3 d1 x( ]; funtil best=0;
- c! q7 w( r6 H- Nend;{bhf}
0 V" H4 @/ h ` y1 z5 v$ V; T' W/ I* x- O* E
B.Floyed算法求解所有顶点对之间的最短路径:
" ]: J! z c4 E% H' Eprocedure floyed;
* _, w: G1 g4 t. u( Bbegin
' U/ n2 R- Y! \$ }for I:=1 to n do ! k) L$ {8 [8 P: x! z7 A- t9 e: W
for j:=1 to n do
8 x# N& ], A5 x: b- C7 v& ]if a[I,j] >0 then p[I,j]:=I else p[I,j]:=0;
- L4 O% l! J5 O# p+ z* j! g$ U{p[I,j]表示I到j的最短路径上j的前驱结点} 8 S! N! f/ O* h; ]( K6 Y
for k:=1 to n do {枚举中间结点}
& ]: y5 W6 m3 ffor i:=1 to n do ' N% `( I! Z# j; P1 X3 d- [
for j:=1 to n do
: U5 a2 b2 u* r7 Z( r5 m8 {if a[i,k]+a[j,k]< a[i,j] then
. ?; J: b! _# o8 P3 S, H: Kbegin 3 B) d" g' C7 e: S7 B! t
a[i,j]:=a[i,k]+a[k,j]; 3 |) V8 z! v" a9 T+ y4 z
p[I,j]:=p[k,j]; + I- `: e8 n: B: @) [# U5 T9 S
end; " k. k! a5 V- S* h* Z; e3 I
end; 1 ^8 i, p" s$ Z4 X& X9 x8 x9 b! J
C. Dijkstra 算法:
3 g* A/ \0 l( \7 [, k8 I$ v0 w8 r类似标号法,本质为贪心算法。 $ |/ X! K8 S# \1 J; G/ h( H
var
+ C% P" _; W( Qa:array[1..maxn,1..maxn] of integer; * {5 s# _1 P) U8 S" w
b,pre:array[1..maxn] of integer; {pre指最短路径上I的前驱结点} " ]/ d7 e* ^2 t
mark:array[1..maxn] of boolean;
K9 w( @! S+ j/ Tprocedure dijkstra(v0:integer);
$ N) J4 Z( r P* v$ N5 V# G% bbegin
0 g9 @$ L; r& ffillchar(mark,sizeof(mark),false); 1 T% y/ g4 m- M3 k/ y }
for i:=1 to n do
$ Z1 ]0 f, n, H/ Rbegin
; \) G; A' a) X( A: V @! zd:=a[v0,i];
" \* M, [! g3 ^) U: x2 `1 {if d< >0 then pre:=v0 else pre:=0; ; h2 K$ g& F. k/ K+ ?3 b* C3 y2 b
end; & o& i% a- X: E$ q0 R- T( v
mark[v0]:=true;
+ u; c ~2 m7 r2 srepeat {每循环一次加入一个离1集合最近的结点并调整其他结点的参数} 4 j- Y$ N+ [8 z4 \6 [
min:=maxint; u:=0; {u记录离1集合最近的结点} ! D% O. \( J# |4 y
for i:=1 to n do 4 X" x, x; @- f* Y4 e% d7 {: p
if (not mark) and (d< min) then . q0 y5 u: w3 a" M/ V% m5 @
begin 3 b- k3 h: W" F# K
u:=i; min:=d;
& Q h# a' w! Q. bend;
5 m% T ^" R* xif u< >0 then
3 B. g1 i( Q Q# j- cbegin
+ N) m3 ] ]; ?$ {5 d2 r2 ^mark:=true; 7 N: m2 x( |9 q9 R* P! \" ~
for i:=1 to n do 5 n. d0 z) z* V. M( P" S2 | C
if (not mark) and (a[u,i]+d< d) then / T: ^3 Y* ~) z& @4 G! P
begin 3 P6 k0 v4 t6 @0 V* y' h
d:=a[u,i]+d;
9 E/ D1 p3 v& F* A- h* Kpre:=u; 1 u! W. h+ ]" {3 W1 o8 L% Q0 x
end;
) X( x V7 P4 s' [$ F7 g) M3 {end; . w T! n+ Q1 {$ w& ?& C9 k- B
until u=0; : _ ~. w" ~4 j& x1 `
end;
, o/ \; T0 Y3 Z% k& l1 _5 i0 \D.计算图的传递闭包
7 l7 F& u { C* T( s. u. ~: ]Procedure Longlink; 7 l+ n L2 }5 J* @1 Y# ]4 a4 f
Var
0 N" E/ A! ~0 C7 zT:array[1..maxn,1..maxn] of boolean;
& [4 Y5 B2 O( q; N8 R7 JBegin 8 @ _+ y' h0 g6 K" i) q( l. { f" S
Fillchar(t,sizeof(t),false);
7 |% n4 @- t% q; ]& YFor k:=1 to n do
, w, ^7 W! f+ `2 R xFor I:=1 to n do
2 J1 M" m1 z) V7 s# HFor j:=1 to n do
+ F- i' x& e: l& i2 tT[I,j]:=t[I,j] or (t[I,k] and t[k,j]);
2 J5 `& b! B% G FEnd;# a% Z5 B, \1 f* d+ s
2 \. K' T) R6 V |
zan
|