1、时 间: 2009-8-20 地 点: N讲述人: noip2007 记录人: li_主 题: 基本算法模块基本算法模块For NOIP2007Billy.Linux模块目录一、 排序1 选择排序2 插入排序3 冒泡排序4 快速排序5 堆排序6 归并排序7 线性时间排序二、 高精度1 高精度比较2 高精度加法3 高精度减法4 单精度乘法5 高精度乘法6 单精度除法7 高精度除法8 进制转换三、 数论Note1 欧几里德算法2 扩展欧几里德3 求最小公倍数4 求解线形同余方程5 素数的判断6 素数的生成四、 排列组合1 排列生成算法2 组合生成算法3 排列按序生成法4 排列字典序生成法五、 图论
2、1 图的读入2 深度优先搜索3 广度优先搜索4 强连同分量5 拓扑排序6 最小生成树7 最短路径六、 背包问题1 装满背包2 一维价值最大背包3 二位价值最大背包一、 排序算法vara:array1maxnof longint;排序对象1 选择排序Select_sortprocedure select_sort;beginfor i:=1 to n-1 dofor j:=i+1 to n doif aiaj thenbegin temp:=ai;ai:=aj;aj:=temp;end;end;2 插入排序Insert_sortprocedure insert_sort;beginfor i:=
3、2 to n dobeginkey:=ai;j:=i-1;while (key0) do begin aj+1:=aj;dec(j);end;aj+1:=key;end;end;3 冒泡排序Bubble_sortprocedure bubble_sort;beginfor i:=1 to n-1 dofor j:=n downto i+1 doif ajx do dec(j);找右边比他小的if ij;if s0 do inc(a0);while bb0+10 do inc(b0);if a0b0 then exit(1);if a0bi then exit(1);if aib0then c0
4、:=a0else c0:=b0;for i:=1 to a0 do inc(ci,ai);for i:=1 to b0 do inc(ci,bi);for i:=1 to c0 dobegininc(ci+1,ci div maxcount);ci:=ci mod 10;end;while cc0+10 dobegininc(c0);inc(cc0+1,cc0 div maxcount);cc0:=cc0 mod maxcount;end;end;3 高精度减法procedure minus(a,b:bignum;var c:bignum);vari:longint;beginfillchar
5、(c,sizeof(c),0);c0:=a0;for i:=1 to c0 do ci:=ai-bi;for i:=1 to c0 doif ci1)and(cc0=0) do dec(c0);end;4 单精度乘法procedure mulnum(a:bignum;x:longint,var c:bignum);vari:longint;beginfillchar(c,sizeof(c),0);c0:=a0;for i:=1 to c0 do ci:=ai*x;for i:=1 to c0 dobegininc(ci+1,ci div maxcount);ci:=ci mod 10;end;
6、while cc0+10 dobegininc(c0);inc(cc0+1,cc0 div maxcount);cc0:=cc0 mod maxcount;end;end;5 高精度乘法procedure mul(a,b:bignum;var c:bignum);vari,j:longint;beginfillchar(c,sizeof(c),0);c0:=a0+b0-1;for i:=1 to a0 dofor j:=1 to b0 doinc(ci+j-1,ai*bj);for i:=1 to c0 dobegininc(ci+1,ci div maxcount);ci:=ci mod 1
7、0;end;while cc0+10 dobegininc(c0);inc(cc0+1,cc0 div maxcount);cc0:=cc0 mod maxcount;end;end;6 单精度除法function divnum(a:bignum;x:longint;var c:bignum):longint;vari,temp:longint;beginfillchar(c,sizeof(c),0);c0:=a0;temp:=0;for i:=a0 downto 1 dobegintemp:=temp*maxcount+ai;ci:=temp div x;temp:=temp mod x;e
8、nd;while (co1)and(cc0=0) do dec(c0);exit(temp);end;7 高精度除法procedure div(a,b:bignum;var c,d:bignum);vari:longint;beginfillchar(c,sizeof(c),0);c0:=a0-b0+1;fillchar(d,sizeof(d),0);d0:=1;for i:=c0 downto 1 dobeginci:=maxcount;repeatdec(ci);mul(c,b,temp); 这里可以用二分法 until compare(a,temp)=0;end;while (c01)a
9、nd(cc0=0) do dec(c0);minus(a,temp,d);end;8 进制转换10进制数用 bignum 记,maxcount=10k 进制数用 string 记constrepchar:array035of string=(0,1,2,a,b,z);数码对应的字符repnum:array48122of longint=(0,1,2,34,35);字符的 ASCCI 码对应的数码k 进制转十进制:procedure change_to_ten(s:string;k:longint):bignum;vari,l:longint;temp:bignum;beginl:=length
10、(s);temp0:=1;temp1:=repnumord(sl);for i:=1 to l-1 dobegininc(temp1,repnumord(sl-i);mulnum(temp,k);end;exit(temp);end;十进制转 k 进制:procedure change_to_k(num:bignum;k:longint):string;vari,temp:longint;s:string;beginif (num0=1)and(num1=0) then exit(0);while not(num0=1)and(num1=0) dobegintemp:=divnum(num,k
11、,num);s:=repchartemp+s;end;exit(s);end;三、 数论算法1 求最大公约数gcd(欧几里德算法)递归(recursion) :function gcd(a,b:longint):longint;beginif b=0 then exit(a);exit(gcd(b,a mod b);end;非递归(iterative):function gcd(a,b:longint):longint;vart:longint;beginwhile b0then ans.ansnum:=0else beginans.ansnum:=d;temp:=(x*(b div d)mo
12、d n;for i:=1 to d do ans.numi:=(temp+i*(n div d)mod n;end;end;5 素数的判断function prime_bool(x:longint):boolean;vari:longint;beginfor i:=2 to trunc(sqrt(x) doif x mod i=0 then exit(false);exit(true);end;6 素数的生成maxnum=生成质数的范围maxprime=对应范围中的质数个数varprime:array0maxprimeof longint;存储质数bool:array1maxnnumof bo
13、olean;存储每个数是不是质数procedure prime_make;vari,j:longint;beginfillchar(bool,sizeof(bool),0);i:=2;while i1)and(ai=closed;end;4 强连通分量varconnected:array1maxn,0maxnof longint;connecti,0为此分量包含的节点数total:longint;强连同分量的个数procedure strongly_connected;vari,time:longint;flag:array1maxnof boolean;sign:array1maxnof l
14、ongint;procedure sort1(t:longint);vari:longint;beginflagt:=true;for i:=1 to n doif (mapt,i0) thensort2(i);inc(connectedtotal,0);connectedtotal,connetedtotal,0:=t;end;beginfillchar(flag,sizeof(flag),0);for i:=1 to n doif not flagi thensort1(i);for i:=n downto 1 doif not flagsigni thenbegininc(total);
15、sort(signi);end;end;5 拓扑排序procedure topological_sort;vari,open,closed:longint;flag:array1maxnof boolean;beginopen:=0;closed:=0;for i:=1 to n doif invi=0 thenbegininc(closed);flagi:=true;AOVclosed:=i;end;if closed=0 then exiterror;repeatinc(open);v:=AOVopen;for i:=1 to vetexv,0 doif not flagvetexv,i
16、thenbegindec(invvetexv,i);if invvetexv,i=0 thenbegininc(closed);AOVclosed:=vetexv,i;flagvetexv,i:=true;end;end;until open=closed;if closedmapmj,vmj,j) thenlowcostvmj,j:=mapmj,vmj,j;end;end;Kruskal以边为基础读入:procedure kruskal;varset1,set2,vetex_pointer,last_set_num:longint;function find(x:longint):longi
17、nt;beginif fatherx=x then find:=fatherxelse begin fatherx:=find(fatherx);find:=fatherx;end;end;beginqsort(1,e);对 vetex 以 w 为关键字从小到大排序for i:=1 to n do fatheri:=i;vetex_pointer:=1;last_set_num:=n;while (last_set_num1)and(vetex_pointerset2 thenbegininc(totallen,vetexvetex_pointer.w);dec(last_set_num);f
18、atherset1:=set2;end;inc(vetex_pointer);end;writeln(totallen);end;7 最短路径Dijktra:procedure Dijkstra(s:longint);vari,j,min,mi:longint;beginfillchar(shortest,sizeof(shortest),$5F);shortests:=0;for i:=1 to n dobeginmin:=max;for j:=1 to n doif (not flagj)and(shortestjmin+mapmi,vetexmi,j) thenshortestvetexmi,j:=min+mapmi,vetexmi,j;end;end;Floyd:procedure Floyd;vari,j,k:longint;