




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、备战 NOIP2006 不可不看的算法一、数论算法1求两数的最大公约数functionbegin(a,b:eger):eger;if b=0 then:=a(b,a mod b);elseend ;:=2求两数的最小公倍数function lcm(a,b:begineger):eger;if a0 end;3素数的求法nc(lcm,a);A.小范围内判断一个数是否为质数:function prime (n:eger):;var I:begineger;for I:=2 to trunc(sqrt(n) do if n mod I=0 then beginprime:=false; exit;
2、end;prime:=true;end;B.判断long范围内的数是否为素数(包含求 50000 以内的素数表):procedure getprime;vari,j:long;p:array1.50000 of beginfillchar(p,sizeof(p),true);p1:=false; i:=2;while i50000 do begin if p then beginj:=i*2;while j=x then breakelse if x mod pr=0 then exit; prime:=true;end;prime二、图论算法 1最小生成树 A.Prim 算法:procedu
3、re prim(v0:vareger);lowcost,closest:array1.maxn ofeger;i,j,k,min:begineger;for i:=1 to n do begin lowcost:=costv0,i; closest:=v0;end;for i:=1 to n-1 do begin寻找离生成树最近的未加入顶点 k min:=maxlong;for j:=1 to n doif (lowcostjmin) and (lowcostj0) then begin min:=lowcostj;k:=j; end;lowcostk:=0; 将顶点k 加入生成树生成树中增加
4、一条新的边k 到closestk修正各点的lowcost 和closest 值 for j:=1 to n doif costk,jlwocostj then begin lowcostj:=costk,j; closestj:=k;end; end;end;prim B.Kruskal 算法:(贪心)按权值递增顺序删去图中的边,若不形成回路则将此边加入最小生成树。function find(v: var i:eger; begini:=1;eger):eger; 返回顶点v 所在的集合while (i=n) and (not v in vset) if i0 do begin i:=find
5、(eq.v1);j:=find(eq.v2); if ij then begin inc(tot,eq.len); vset:=vset+vsetj;vsetj:=; dec(p);end; inc(q);end;wriend;n(tot);2.最短路径A.标号法求解单源点最短路径: vara:array1.maxn,1.maxn ofeger;b:array1.maxn ofeger; b 指顶点i 到源点的最短路径mark:array1.maxn of;procedure var best,best_j:begin;eger;fillchar(mark,sizeof(mark),false
6、); mark1:=true; b1:=0;1 为源点repeatbest:=0;for i:=1 to n doIf mark then 对每一个已计算出最短路径的点 for j:=1 to n doif (not markj) and (ai,j0) thenif (best=0) or (b+ai,j0 then begin bbest_j:=best;markbest_j:=true;end;until best=0;end;B.Floyed 算法求解所有顶点对之间的最短路径:procedure floyed; beginfor I:=1 to n dofor j:=1 to n do
7、if aI,j0 then pI,j:=I els路径上j 的前驱结点,j:=0; pI,j表示I 到j 的最短for k:=1 to n do 枚举中间结点 for i:=1 to n dofor j:=1 to n doif ai,k+aj,kai,j then begin ai,j:=ai,k+ak,j;pI,j:=pk,j; end;end;C. Dijkstra 算法:vara:array1.maxn,1.maxn ofeger;b,pre:array1.maxn of结点mark:array1.maxn ofeger; pre 指最短路径上I 的前驱;procedure dijks
8、tra(v0:begineger);fillchar(mark,sizeof(mark),false); for i:=1 to n do begind:=av0,i;if d0 then pre:=v0 else pre:=0; end;markv0:=true;repeat的参数每循环一次加入一个离 1 集合最近的结点并调整其他结点min:=max; u:=0; u离 1 集合最近的结点for i:=1 to n doif (not mark) and (dmin) then begin u:=i; min:=d;end;if u0 then begin mark:=true;for i:
9、=1 to n doif (not mark) and (au,i+dd) then begin d:=au,i+d;pre:=u; end; end;until u=0; end;3.计算图的传递闭包Procedure Longlink; VarT:array1.maxn,1.maxn of Begin Fillchar(t,sizeof(t),false);For k:=1 to n doFor I:=1 to n do;For j:=1 to n do TI,j:=tI,j or (tI,k and tk,j);End;4无向图的连通分量 A.深度优先procedure dfs ( no
10、w,color: beginfor i:=1 to n doeger);if anow,i and c=0 then begin 对结点I 染色 c:=color;dfs(I,color); end;end;B 宽度优先(染色法)5关键路径几个定义: 顶点 1 为源点,n 为汇点。a. 顶点事件最早发生时间Vej, Ve j = max Ve j + wI,j ,其中Ve (1) = 0;b.中c.顶点事件最晚发生时间 Vlj, Vl j = min Vlj wI,j ,其 Vl(n) = Ve(n);边活动最早开始时间 EeI, 若边I 由表示,则 EeI = Vej;d. 边活动最晚开始时
11、间 ElI, 若边I 由表示,则ElI = Vlk wj,k;若 Eej = Elj ,则活动j 为关键活动,由关键活动组成的路径为关键路径。求解方法:从源点起topsort,判断是否有回路并计算Ve;从汇点起topsort,求Vl;算Ee 和 El;6拓扑排序找入度为 0 的点,删去与其相连的所有边,不断重复这一过程。例 寻找一数列,其中任意连续p 项之和为正,任意q 项之和为负,若不存在则输出NO.7.回路问题 Euler 回路(DFS)定义:经过图的每条边仅一次的回路。(充要条件:图连同且无奇点)Hamilton 回路定义:经过图的每个顶点仅一次的回路。一笔画充要条件:图连通且奇点个数为
12、 0 个或 2 个。判断图中是否有负权回路 Bellman-ford 算法xI,yI,tI分别表示第I 条边的起点,终点和权。共 n 个结点和m 条边。procedure bellman-ford beginfor I:=0 to n-1 do dI:=+infinitive; d0:=0;for I:=1 to n-1 dofor j:=1 to m do 枚举每一条边if dxj+tjdyj then dyj:=dxj+tj; for I:=1 to m doif dxj+tjdyj then return false else return true; end;第 n 最短路径问题*第二
13、最短路径:每举最短路径上的每条边,每次删除一条,然后求新图的最短路径,取这些路径中最短的一条即为第二最短路径。*同理,第n 最短路径可在求解第n-1 最短路径的基础上求解。三、背包问题*部分背包问题可有贪心法求解:计算Pi/Wi数据结构:w:第i 个背包的重量;p:第i 个背包的价值;10-1 背包: 每个背包只能使用一次或有限次(可转化为一次):A.求最多可放入的重量。 NOIP2001 装箱问题有一个箱子容量为 v(正整数,ov20000),同时有 n 个物品(on30),每个物品有一积 (正整数)。要求从 n 个物品中,任取若千个装入箱内,使箱子的剩余空间为最小。l 搜索方法proced
14、ure search(k,v:veger); 搜索第k 个物品,剩余空间为var i,j:begineger;if v=best then exit; sn为前n 个物品的重量和if kwk then search(k+1,v-wk); search(k+1,v);end; end;l DPFI,j为前i 个物品中选择若干个放入使其体积正好为j 的标志,为型。实现:将最优化问题转化为判定性问题f I, j = f i-1, j-w (wI=j0 thenif j+now=n then inc(cj+now,aj); a:=c;end; 2可重复背包A 求最多可放入的重量。FI,j为前i 个物品
15、中选择若干个放入使其体积正好为j 的标志,为型。状态转移方程为fI,j = f I-1, j wI*k (k=1. j div wI) B.求可以放入的最大价值。USACO 1.2 Score Inflation进行一次竞赛,总时间T 固定,有若干种可选择的题目,每种题目可选入的数量不限,每种题目有一个 ti(解答此题所需的时间)和一个 si(解答此题所得的分数),现要选择若干题目,使解这些题的总时间在 T 以内的前提下,所得的总分最大,求最大的得分。*易想到:fi,j = max f i- k*wj, j-1 + k*pj (0=k=0 Then Begint:=problemj.po+fi
16、-problemj.time;If tf Then f:=t; End;Wrin(fM); End.C.求恰好装满的情况数。 Ahoi2001 Problem2求自然数n 本质不同的质数和的表达式的数目。思路一,生成每个质数的系数的排列,在一一测试,这是通法。procedure try(dnteger);var i,j:begineger;cal; 此过程计算当前系数的计算结果,now 为结果 if nown then exit; 剪枝if dep=l+1 then begin 生成所有系数 cal;if now=n then inc(tot); exit;end;for i:=0 to n
17、div prdep do begin xsdep:=i;try(dep+1); xsdep:=0; end;end;思路二,递归搜索效率较高procedure try(dep,rest:eger);var i,j,x:begineger;if (rest0 thenfor k:=1 to n div now doif j+now*k=n then inc(cj+now*k,aj); a:=c;end;main beginread(now); 读入第一个物品的重量i:=0;a 为背包容量为i 时的放法总数while i=n do begina:=1; inc(i,now); end; 定义第一个
18、物品重的整数倍的重量a 值为1,作为初值 for i:=2 to v do beginread(now); update; 动态更新end;wrin(an);四、排序算法1.快速排序:procedure qsort(l,r:eger);var i,j,mid:eger;begini:=l;j:=r; mid:=a(l+r) div 2; 将当前序列在中间位置的数定义为中间数repeatwhile amid do dec(j);在右半部分寻找比中间数小的数if ij;if lj then qsort(l,j); 若未到两个数的边界,则递归搜索左右区间 if ir then qsort(i,r);
19、end;sortB.排序:思路:当前a1.ai-1已排好序了,现要procedure insert_sort;a 使a1.a 有序。var i,j:begineger;for i:=2 to n do begin a0:=a;j:=i-1;while a0aj then swap(a,aj); end;D. 冒泡排序procedure bubble_sort;var i,j,k:begineger;for i:=1 to n-1 dofor j:=n downto i+1 doif ajaj-1 then swap( aj,aj-1); 每次比较相邻元素的关系end;E.堆排序:procedu
20、re sift(i,m:总数eger);调整以i 为根的成为堆,m 为结点var k:begineger;a0:=a; k:=2*i;在完全二叉树中结点i 的左孩子为 2*i,右孩子为 2*i+1while k=m do beginif (km) and (akak+1) then inc(k);找出ak与ak+1中较大值if a0ak then begin a:=ak;i:=k;k:=2*i; end else k:=m+1;end;a:=a0; 将根放在合适的位置 end;procedure heapsort;varj:begineger;for j:=n div 2 downto 1 d
21、o sift(j,n);for j:=n downto 2 do begin swap(a1,aj);sift(1,j-1); end;end;F. 归并排序a 为序列表,tmp 为辅助数组 procedure merge(var a:listtype; p,q,r:eger);将已排序好的子序列ap.q与aq+1.r合并为有序的tmpp.rvar I,j,t:eger;tmp:listtype; begint:=p;i:=p;j:=q+1;t 为tmp 指针,I,j 分别为左右子序列的指针 while (t=r) do beginif (ir) or (a=aj) 满足取左边序列当前元素的要
22、求then begin tmpt:=a; inc(i);endelse begin tmpt:=aj;inc(j);end; inc(t);end;for i:=p to r do a:=tmp; end;mergeprocedure merge_sort(var a:listtype; p,r:ap.reger); 合并排序var q:begineger;if pr then begin q:=(p+r-1) div 2; merge_sort (a,p,q);merge_sort (a,q+1,r);merge (a,p,q,r); end;end;main beginmerge_sort
23、(a,1,n); end.G.基数排序:对每个元素按从低位到五、高精度计算对每一位进行一次排序高精度数的定义:typehp=array1.maxlen of 1高精度加法eger;procedure plus ( a,b:hp; var c:hp);var i,len:begineger;fillchar(c,sizeof(c),0);if a0b0 then len:=a0 else len:=b0; for i:=1 to len do begininc(c,a+b);if c10 then begin dec(c,10); inc(ci+1); end; 进位 end;if clen+1
24、0 then inc(len); c0:=len;end;plus 2高精度减法procedure substract(a,b:hp;var c:hp);var i,len:begineger;fillchar(c,sizeof(c),0);if a0b0 then len:=a0 else len:=b0; for i:=1 to len do begininc(c,a-b);if c1) and (clen=0) do dec(len);c0:=len; end;3高精度乘以低精度procedure multiply(a:hp;b:long;var c:hp);var i,len:begi
25、neger;fillchar(c,sizeof(c),0); len:=a0;for i:=1 to len do begin inc(c,a*b); inc(ci+1,(a*b) div 10);c:=c mod 10; end;inc(len);while (clen=10) do begin 处理最 clen+1:=clen div 10;clen:=clen mod 10; inc(len);end;的进位while (len1) and (clen=0) do dec(len); 若不需进位则调整 lenc0:=len; end;multiply 4高精度乘以高精度procedure
26、 high_multiply(a,b:hp; var c:hpvar i,j,len:begineger;fillchar(c,sizeof(c),0); for i:=1 to a0 dofor j:=1 to b0 do begin inc(ci+j-1,a*bj);inc(ci+j,ci+j-1 div 10);ci+j-1:=ci+j-1 mod 10; end;len:=a0+b0+1;while (len1) and (clen=0) do dec(len); c0:=len;end;5高精度除以低精度procedure devide(a:hp;b:longc:=a div b;
27、d:= a mod b; var c:hp; var d:long);var i,len:begineger;fillchar(c,sizeof(c),0); len:=a0; d:=0;for i:=len downto 1 do begin d:=d*10+a;c:=d div b; d:=d mod b;end;while (len1) and (clen=0) then dec(len); c0:=len;end; 6高精度除以高精度procedure high_devide(a,b:hp; var c,d:hp);vari,len:begineger;fillchar(c,sizeo
28、f(c),0); fillchar(d,sizeof(d),0); len:=a0;d0:=1;for i:=len downto 1 do begin multiply(d,10,d);d1:=a;while(compare(d,b)=0) do 即d=b beginSubtract(d,b,d); inc(c);end; end;while(len1)an c.len:=len;end;len=0) do dec(len);六、 树的遍历1已知前序中序求后序procedure Solve(pre,mid:string);var i:begineger;if (pre=) or (mid=)
29、 then exit;i:=(pre1,mid);solve(copy(pre,2,i),copy(mid,1,i-1); solve(copy(pre,i+1,length(pre)-i),copy(mid,i+1,length(mid)-i);t:=t+pre1; 加上根,递归结束后t 即为后序遍历end; 2已知中序后序求前序procedure Solve(mid,t:string);var i:begineger;if (mid=) or (t=) then exit;i:=(tlength(tlength(t),mid);t); 加上根,递归结束后pre 即为前pre:=pre+序遍
30、历solve(copy(mid,1,I-1),copy(t,1,I-1);solve(copy(mid,I+1,length(mid)-I),copy()-i);end;t,I,length(t3已知前序后序求中序的一种function ok(s1,s2:string):;var i,l:begineger;p:;ok:=true; l:=length(s1);for i:=1 to l do begin p:=false;for j:=1 to l doif s1=s2j then p:=true;if not p then begin ok:=false;exit;end; end;end
31、;procedure solve(pre,t:string);var i:begineger;if (pre=) or ( i:=0;repeatinc(i);t=) then exit;until ok(copy(pre,2,i),copy(t,1,i);solve(copy(pre,2,i),copy(midstr:=midstr+pre1;t,1,i);solve(copy(pre,i+2,length(pre)-i-1),copy( ost)-i-1);end;t,i+1,length(p七 进制转换任意正整数进制间的互化除n 取余实数任意正整数进制间的互化乘n 取整负数进制:设计一个
32、程序,读入一个十进制数的基数和一个负进制数的基数,并将此十进制数转换为此负 进制下的数:-R-2,-3,-4,.-20八 全排列与组合的生成1 排列的生成:(1.n)procedure solve(d varnteger);i:eger;beginif dep=n+1 then begin wri for i:=1 to n doif not used then beginn(s);exit; end;s:=s+chr(i+ord(0);used:=true; solve(dep+1);s:=copy(s,1,length(s)-1); used:=false; end;end;2 组合的生成
33、(1.n 中选取k 个数的所有方案)procedure solve(dep,pre:vareger);i:eger;beginif dep=k+1 then begin wri for i:=1 to n don(s);exit; end;if (not used) and (ipre) then begin s:=s+chr(i+ord(0);used:=true; solve(dep+1,i);s:=copy(s,1,length(s)-1); used:=false; end;end;九.查找算法1 折半查找function binsearch(k:keytype): var low,h
34、ig,mid:eger;beginlow:=1;hig:=n; mid:=(low+hig) div 2;eger;while (amid.keyk) and (lowk then hig:=mid-1 else low:=mid+1; mid:=(low+hig) div 2;end;if lowhig then mid:=0; binsearch:=mid;end;2 树形查找二叉排序树:每个结点的值都大于其树任一结点的值。树任一结点的值而小于其右子查找function treesrh(k:keytype):poer;var q:po beginq:=root;er;while (qnil
35、) and (q.keyk) do if kq.key then q:=q.leftelse q:=q.right; treesrh:=q;end;十、贪心*会议问题(1) n 个活动每个活动有一个开始时间和一个结束时间,任一时刻仅一项活动进行,求满足活动数最多的情况。解:按每项活动的结束时间进行排序,排(2)会议室空闲时间最少。面的优先满足。(3)每个客户有一个愿付的,求最大利润。(4)共 R 间会议室,第i 个客户需使用i 间会议室,费用相同,求最大利润。十一、回溯法框架1. n 皇后问题procedure try(i:byte); var j:byte;beginif i=n+1 the
36、n begin pr for j:=1 to n do;exit;end;if a and bj+i and cj-i then begin x:=j;aj:=false; bj+i:=false; cj-i:=false; try(i+1);aj:=true; bi+j:=true; cj-i:=true; end;end;2.Hanoi Towerh(n)=2*h(n-1)+1h(1)=1初始所有铜片都在a 柱上procedure hanoi(n,a,b,c:byte); 将第n 块铜片从a 柱通过b 柱移到c 柱上beginif n=0 then exit;hanoi(n-1,a,c,b
37、); 将上面的n-1 块从a 柱通过c 柱移到b 柱上write(n,moved from,a,to,c);hanoi(n-1,b,a,c); 将b 上的n-1 块从b 柱通过a 柱移到c 柱上end;初始铜片分布在 3 个柱上,给定目标柱goalh1.3,0.n存放三个柱的状态,now 与nowp 存最大的的柱号和,hI,0存第I 个柱上的个数。的铜片Procedure move(k,goal:eger); 将最大 goal 上BeginIf k=0 then exit; For I:=1 to 3 doFor j:=1 to hanI,0 do的k 移到目标柱If hI,j=k then
38、begin now:=I;nowp:=j; end; 找到k 的位置 If nowgoal then begin 若未移到目标Move(k-1,6-now-goal); 剩下的先移到没用的柱上Wrin(k moved from now to goal);Hgoal,hgoal,0+1:=hnow,nowp; hnow,nowp:=0;Inc(hgoal,0); dec(hnow,0); Move(k-1,goal); 剩下的移到目标上End;十二、DFS 框架NOIP2001 数的划分procedure work(dep,pre,s:long); 为work(1,1,n)dep 为当前试放的第
39、dep 个数,pre 为前一次试放的数,s 为当前剩余可分的总数var j:longbegin;if dep=n then beginif s=pre then inc(r); exit; end;for j:=pre to s div 2 do work(dep+1,j,s-j); end;类似:procedure try(dnteger);var i:begineger;if dep=k then beginif tot=adep-1 then inc(sum); exit; end;for i:=adep-1 to tot div 2 do begin adep:=i; dec(tot,
40、i);try(dep+1); inc(tot,i); end;end;try十三、BFS 框架 IOI94 房间问题 head:=1; tail:=0;while tail=1) and (I=L.len) thenwhile jI do begin p:=p.next; inc(j); end; loc:=p;end;2单链表的操作procedure insert(L:linklist; I:eger; x:da var p,q:poer;begin p:=loc(L,I); new(q); q.data:=x;q.next:=p.next; p.next:=q; inc(L.len);end;3单链表的删除操作ype);procedure dele:linklist; I:eger);var p,q:pobeginer;p:=loc(L,I-1);q:=p.next; p.next:=q.next;dise(q);dec(L.len); end; 4双链表的 p:=loc(L,I); new(q); q.data:=x;q.pre:=p;新结点q)操作(q.next:=p.next; p.next:=q; q.next.pre:=q; 5双链表的删除操作 p:=loc(L,I); p
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年4月抄表核算收费员-初级工模拟考试题(含答案解析)
- 蔬菜加工中的微生物控制考核试卷
- 学前教育顶岗实习工作说明
- 石材开采工艺与设备选型考核试卷
- 节能型缝制设备开发考核试卷
- 《H组网技术》课件
- 帆船幼儿美术课件
- 草原割草在规范行业发展中的作用考核试卷
- 航空货运业务中的航空器装载技术改进考核试卷
- 《看电影》活动设计
- 2024年陕西省普通高中学业水平合格性考试历史试题(解析版)
- 中国干眼临床诊疗专家共识(2024年)解读
- 2mm土工膜长丝土工布检测报告合格证
- 一年级家长会课件2024-2025学年
- 拉美文化学习通超星期末考试答案章节答案2024年
- 文艺复兴经典名著选读智慧树知到期末考试答案章节答案2024年北京大学
- 小小科学家《物理》模拟试卷A(附答案)
- 体能科学训练方法智慧树知到期末考试答案2024年
- GB/T 18175-2014水处理剂缓蚀性能的测定旋转挂片法
- (参考)混凝土配合比设计原始记录
- 坤集心法解密(兼论铁板神数扣入起数)
评论
0/150
提交评论