- 在线时间
- 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 ~4 s u' [! P6 [. l% w3 c
求两数的最大公约数 * x/ j/ A* ]7 b k
function gcd(a,b:integer):integer;
1 R: ~& j! z. l( x! R) ^0 T7 `1 Xbegin / a3 ^& }$ {2 b* p% m
if b=0 then gcd:=a " k: a& d4 d! v* @1 X& Q) i, F& A
else gcd:=gcd (b,a mod b); ( e5 |5 W5 g! v3 J
end ; 3 t8 ` M/ w% p0 {! x3 R
: _1 R2 B; x# N' V! i
求两数的最小公倍数 : d6 D) m: h! m8 k
function lcm(a,b:integer):integer; 6 h, O2 l- C8 c2 |7 Z
begin
4 w# C" u2 f7 Z z u) Cif a< b then swap(a,b); . D% p- B$ U. Y( d* y0 Q
lcm:=a; @ O1 U" H9 c2 {
while lcm mod b >0 do inc(lcm,a); 6 _! s5 I' C* t* G5 o
end;
5 j% z" A# Z/ q/ E) P8 D9 c1 @0 ?$ `6 k1 T d; _# u1 Y# J
素数的求法
$ p( h; m4 Y: ~, Y) |% c; IA.小范围内判断一个数是否为质数: " x. U1 T8 ?$ ~- H* L7 u
function prime (n: integer): Boolean;
4 T, v! m- N3 N" L* ]8 Rvar I: integer; & v7 s. J1 l2 O( @5 L& P9 |; Z
begin 2 }1 m( T a+ a! v- o2 s' h
for I:=2 to trunc(sqrt(n)) do
% M& T7 X, Y' J; }if n mod I=0 then ) B! }/ m* ~' R& f7 U- W5 Z
begin ) ^# q/ D* C3 |. Y5 M$ B5 e
prime:=false; exit; 3 r% d7 Z: E, l
end;
$ c+ C3 G5 } w; U. jprime:=true;
- o8 J( }3 |0 }4 z- C( e7 K6 r' c) Nend;
0 p9 ?4 K5 b8 G% w
- J# R2 @ C8 c: WB.判断longint范围内的数是否为素数(包含求50000以内的素数表): : O- z; g5 n$ _5 j: Z: I
procedure getprime; , R8 I6 Y o4 U& ^. R \3 X
var ) u6 l3 b' D& d# P
i,j:longint; - D; n% B G+ w% s3 x, a
p:array[1..50000] of boolean;
% z0 _) ?% U$ |begin r8 {% ?5 D+ a H6 H. N
fillchar(p,sizeof(p),true);
: w/ z! D' }# Q( j( A' ~+ F3 K: ]p[1]:=false; & j4 g& U. S* O0 Z
i:=2; % R9 K G# M+ [5 H6 A
while i< 50000 do ( g3 I. y2 g1 i: H/ d" m
begin
& ^5 x9 S! g- p8 Q4 S. Zif p then 5 k9 X& I7 K: e8 B
begin
) ?2 Z& Q0 s( Mj:=i*2;
) O9 ? V4 _( s- i# n; |6 nwhile j< 50000 do
5 E' n- F6 c% Y+ r" ?begin ( m. E0 i3 C P
p[j]:=false; W: O) U- v% H! n+ z5 {
inc(j,i);
e2 j2 b6 O" L0 y8 L) z& X- pend;
( I# U/ q* J& O; A! G8 v. nend;
& t- b, b: p5 Pinc(i);
( |4 w* _/ }! H# @/ k. M5 lend;
9 v. A$ ?* n8 w3 tl:=0; ) g* O6 \! D& c! B) E7 @: A; ~
for i:=1 to 50000 do
' d1 B* S$ C( U4 F; e6 @* z" r/ nif p then
' m3 G! y: }4 }1 v1 F0 R; q! ]begin ! I+ K g- Y2 @
inc(l);
U; q: ]- Y; Q. Spr[l]:=i;
' q6 o- S( y p' F, `/ h9 uend; * p0 D D6 a7 E
end;{getprime}
' A- J' F g: O) u! f, ~7 Y' F6 Jfunction prime(x:longint):integer;
; {# w; q$ ]1 ]; O7 k# _0 B1 S6 G8 {var i:integer;
6 |) K, R. ?* x9 Kbegin
$ b# M( T2 p; b/ Qprime:=false;
; D$ ?" G$ z( y& w& h0 B+ K5 hfor i:=1 to l do
' H6 p" o* ]5 ~" }if pr >=x then break 7 e& M+ f; g- J% V) t/ {6 @- V% H" S
else if x mod pr=0 then exit;
6 q+ h1 E/ Q0 ^( _" k; u0 qprime:=true;
c* h! d; K7 y/ n2 oend;{prime} 5 i9 D6 n: F# Z$ P/ W, a
8 h. o5 z2 ?+ a9 _2 c, z2. 2 T( T& Z/ \. g1 q
' I4 R4 G: _3 B3 D0 q3. ! E' a! B2 p% I2 D
8 T" h4 S0 e% t. B; {" }; k
4.求最小生成树 % Z! R, m' o5 n5 m3 |
A.Prim算法: 7 ~# J# O1 M/ [% P- K/ {& \5 Z! n
procedure prim(v0:integer);
- p" \$ p$ u% F! Pvar * c& P M/ W. E
lowcost,closest:array[1..maxn] of integer;
% y, \" g5 H5 g& Hi,j,k,min:integer;
: _% r" f, l) S- b2 tbegin
; m) w) N6 N; A4 s& ~# M) afor i:=1 to n do
7 |5 f0 N f# Q4 |" T, B$ \( f5 ]begin . {- ~0 _# s. T2 ?1 s# w
lowcost:=cost[v0,i];
: U1 {* ^- F5 S, `! _closest:=v0;
3 F: f8 N9 D! n g5 w' rend; ' R$ v& c. ^' |5 a
for i:=1 to n-1 do
; X# f) t Z/ D* Ybegin 8 C3 _1 Z- l6 y; t* q4 p9 O
{寻找离生成树最近的未加入顶点k} . s2 N) M- d$ W: r) A4 l
min:=maxlongint;
) \2 z. b0 y- r. G& W3 sfor j:=1 to n do * P+ n8 i* z1 W
if (lowcost[j]< min) and (lowcost[j]< >0) then / X# g: O* o" w$ X5 F
begin
& u+ g$ y' m, F1 l& smin:=lowcost[j];
8 T6 b9 _6 y/ W/ M. r0 r+ i: {k:=j; ! e/ H/ I5 g% O2 m6 w( V
end;
8 S5 k8 X$ O5 f+ a8 ~- \lowcost[k]:=0; {将顶点k加入生成树} ) t/ V3 Q- X; r- {9 s2 ~8 X
{生成树中增加一条新的边k到closest[k]} 8 m7 t6 U3 [+ F6 j- N9 L
{修正各点的lowcost和closest值}
% C& s; X# E0 \# Hfor j:=1 to n do
2 }+ P7 R3 [% _ q( M6 u' Jif cost[k,j]< lwocost[j] then : Q. M/ [1 v$ ^: ]+ O/ p4 f, E
begin 0 J( E% `( Q! F1 H6 `
lowcost[j]:=cost[k,j];
: |3 D! l7 ]+ R3 i$ {, R/ Wclosest[j]:=k;
# t& b. @1 H% ^+ U% Z" O# lend;
$ ?" w. G _/ M p6 {" D/ gend;
$ k- h3 F" O1 M+ W* j8 o8 Uend;{prim}
; s$ L2 Y8 V6 x0 b- b8 |) _, h: ~B.Kruskal算法:(贪心)
' e+ y2 z3 c. [* ]按权值递增顺序删去图中的边,若不形成回路则将此边加入最小生成树。 1 K4 \# ?2 \" @# V1 [
function find(v:integer):integer; {返回顶点v所在的集合}
. x1 B/ i, ~, |; U9 x+ zvar i:integer; - `0 \ q2 ?/ T+ k
begin
( \2 w8 C. p/ g) L. t, c( qi:=1; ) Q- X$ q6 n, L$ b1 D/ B* p
while (i< =n) and (not v in vset) do inc(i); : n* G0 Z1 w5 F: E, E
if i< =n then find:=i
: `8 J5 h5 _2 B2 h; k* Y; kelse find:=0;
2 D+ J5 v+ Z, L% k+ V k2 Zend; # e( h# M) |/ j% J9 e0 c
procedure kruskal;
$ A8 h! h& m7 G. ^$ S# | yvar
. ?; B M* p2 P. a5 D5 ^tot,i,j:integer;
3 P4 n( L& j, L9 ybegin
5 j; \: ?( Q: lfor i:=1 to n do vset:=;{初始化定义n个集合,第I个集合包含一个元素I} g3 }2 U- O5 m w
p:=n-1; q:=1; tot:=0; {p为尚待加入的边数,q为边集指针} . S; M, ~" h8 f6 z1 |7 ^
sort;
0 I5 K# [4 G3 D; h6 B2 z' y{对所有边按权值递增排序,存于e[I]中,e[I].v1与e[I].v2为边I所连接的两个顶点的序号,e[I].len为第I条边的长度}
5 }( N G. n0 i8 v6 Bwhile p >0 do 6 H( X2 n8 R0 U& _0 e, D% N
begin , l% l& e) Y* [) x" K0 X' z
i:=find(e[q].v1);j:=find(e[q].v2); . W! F! ?) }/ o8 J) D
if i< >j then
: o, q, o7 S& \* zbegin
- |' B! L" I* C6 y& @inc(tot,e[q].len); 2 Q8 @/ a' |& l
vset:=vset+vset[j];vset[j]:=[]; " ]: ?6 r9 a [ Q! x% T& L
dec(p);
( |( Y' H' I. L+ d7 nend; , p6 e- Y& D9 w9 a' L
inc(q); 8 K$ R) F3 E: ?, [ P. ^/ P
end; % g% Y1 _8 Q1 G% [
writeln(tot);
8 B$ Y* T/ K* |) oend; * H5 Q T! i$ t( u& ^1 B
+ N* G. H) W$ @6 J- w' e9 _/ m5.最短路径
" P2 B8 s. @) j5 cA.标号法求解单源点最短路径:
, W1 ^3 { c9 h b5 N, d& }var : D: L% q2 I+ y& b" O
a:array[1..maxn,1..maxn] of integer; 8 N; k: r! {3 M' N# x
b:array[1..maxn] of integer; {b指顶点i到源点的最短路径} ( ~' S0 u. o3 h
mark:array[1..maxn] of boolean;
6 y3 V! F3 v j' G2 W( O( K
. q9 N* }" A" |; r9 H/ h; dprocedure bhf; ! v& W$ | @) g; E9 d
var 8 F* c* a% k) k( _- t$ h# o
best,best_j:integer; G" w- ?% s- Z/ j& w2 T
begin 0 o' _, Y9 ]1 j9 H" y. A2 k
fillchar(mark,sizeof(mark),false); 3 c: g8 i8 v! J( C2 h
mark[1]:=true; b[1]:=0;{1为源点} ' c _. x' }) ~. Y% H
repeat
9 D/ v8 K) V- q, @2 Fbest:=0; 0 M& o; u7 N2 l5 ?* ]/ b E
for i:=1 to n do
! g# J. A! _) Q! i& \If mark then {对每一个已计算出最短路径的点}
7 z0 \1 f/ u/ x- q8 T# W9 Nfor j:=1 to n do
% X. Z) o. @3 u* m- ^if (not mark[j]) and (a[i,j] >0) then
" l' m8 \, L W8 z3 t, J5 Tif (best=0) or (b+a[i,j]< best) then
. n$ D: t5 M3 T. B4 `begin
' z. D s7 T6 n I: Fbest:=b+a[i,j]; best_j:=j; ) G) g) H6 [( D- |2 q
end; " F+ v6 u# a0 D; ?+ l
if best >0 then
% C+ H; v) [; [+ w) a( E8 I5 pbegin
1 x( W" o* q: l- [ _4 sb[best_j]:=best;mark[best_j]:=true; , u/ q" q% p9 N# w4 u
end; 4 v1 ]& ^) v0 q: O" M
until best=0;
4 g+ R# _3 @( e& ~1 q L. ]end;{bhf} % u' c0 q }% k/ ]4 X
+ S# F1 n- O0 n, U2 p6 q+ J* w m6 r
B.Floyed算法求解所有顶点对之间的最短路径: % Q9 v6 c' S. x8 _4 |8 f2 }
procedure floyed;
; S8 V- J* c: D+ [( j% r! a; h& jbegin + S* B) S5 F( K: p- u* W
for I:=1 to n do 5 P8 K5 a6 p5 ?/ B4 v3 Q, e
for j:=1 to n do . L8 M- y, t+ R0 s, \) K4 c, `) M
if a[I,j] >0 then p[I,j]:=I else p[I,j]:=0; + C8 O V! d+ ?0 d# ], b7 P
{p[I,j]表示I到j的最短路径上j的前驱结点}
P( g% B7 j, _ x) w3 Bfor k:=1 to n do {枚举中间结点}
1 x( m L3 O8 @7 ofor i:=1 to n do
& @" S! U' c* M: X" ^8 b8 r7 C) ]# U) dfor j:=1 to n do
! M3 _$ \, j: n( o+ eif a[i,k]+a[j,k]< a[i,j] then 1 Y9 x/ G. g, G# L# d
begin
6 }# B: V8 [/ y5 I/ Oa[i,j]:=a[i,k]+a[k,j];
4 ]. a7 ?4 x' c6 L0 E, F' gp[I,j]:=p[k,j];
5 k9 {: p2 ^: o: ]. T; R6 p% `% Vend;
( W. m) ]' v; y$ o% |) l6 @end;
9 o4 _, X; u; S! GC. Dijkstra 算法:
# C& T) m7 p5 b. B' |, E- s类似标号法,本质为贪心算法。 . J0 ~& Q' M8 n1 h+ a2 Q
var
( E s$ x: `; Z. da:array[1..maxn,1..maxn] of integer; 1 m( E5 t# ?3 Z, }! `1 ~
b,pre:array[1..maxn] of integer; {pre指最短路径上I的前驱结点}
5 Z* X$ y, ]- t' h) M! i+ kmark:array[1..maxn] of boolean; . o- S/ j* q- Q" m3 e% o
procedure dijkstra(v0:integer); 7 l$ V; \9 E; r4 _
begin
( ^, P) T+ X+ L2 rfillchar(mark,sizeof(mark),false); 2 E' B" s# L! @6 r% j
for i:=1 to n do , l( j* |) [& z" [
begin
6 r! d2 _ K7 yd:=a[v0,i]; 5 }- ^" r9 `0 m
if d< >0 then pre:=v0 else pre:=0; + V9 D% \" Q3 ~$ n
end; 7 F; d3 a% @6 d" S0 w2 j3 a
mark[v0]:=true;
; w. X( b9 s0 u6 [/ Drepeat {每循环一次加入一个离1集合最近的结点并调整其他结点的参数} / z1 C- \7 p/ b' B
min:=maxint; u:=0; {u记录离1集合最近的结点} , |% k% J5 O/ d1 d( r
for i:=1 to n do
5 v* u! @6 ^% l/ e. a$ I% G" ]if (not mark) and (d< min) then * x- }8 t$ S6 r1 R6 d. q
begin
" k0 c) C, e7 b1 Su:=i; min:=d; . D& j, q; F/ ^1 y3 B( }. {
end;
4 m- u3 e, l) r0 R g: wif u< >0 then : a. t0 n6 }( Y5 d. \4 P, Z
begin * A) \' s+ I" u5 G4 E
mark:=true; - x7 ?* y" ^3 P! K
for i:=1 to n do
3 {6 ]0 q" [& N5 `4 eif (not mark) and (a[u,i]+d< d) then
]7 ^# H" N( ebegin
- z4 M1 l- @2 J7 u6 i$ ]d:=a[u,i]+d;
* q1 R' ?+ Y5 K8 J+ ]# Bpre:=u;
4 r. R" M$ w/ N5 W& Pend;
, p' U$ s* s. xend;
" B# J, i0 l+ r2 Y, ^$ D% S2 O% Iuntil u=0; 5 j% K* G! D3 ?, t+ `
end; ) u# h: N9 t) H$ @1 J" I# U8 Y
D.计算图的传递闭包 $ v& l0 o8 A8 H* H) C
Procedure Longlink;
1 Q3 @! ^9 N+ |Var 0 X ^/ W4 j; i
T:array[1..maxn,1..maxn] of boolean;
- m+ |# u; [) g2 ^4 ~1 O9 UBegin . A- n/ m8 k! N, B( e
Fillchar(t,sizeof(t),false); $ S5 R- N2 x7 c6 _: Q3 O8 \
For k:=1 to n do 3 e3 D `/ i2 S( b
For I:=1 to n do
) ^5 B9 X( Z2 U$ `- sFor j:=1 to n do 0 N0 D. I* F8 t( g9 B
T[I,j]:=t[I,j] or (t[I,k] and t[k,j]);
6 M$ n, G& G5 c) M$ @! b' H; [End;
" m& R6 {3 B$ L) f; A1 i# G, ^2 d( S; ]0 b3 g
|
zan
|