基础代码汇总整理 for NOIP 2009 修订版(上)
来源:互联网 发布:心动网络 仙境传说 编辑:程序博客网 时间:2024/06/15 21:43
修订版序言
NOIP2009出乎意料地死掉了。不能说没有没发挥出来的地方,但我确实可能还有很多需要完善的地方。也许是自以为省一已经是囊中之物,有些不知天高地厚了吧!不过既然已经努力过了我也就没什么遗憾了。跟我的学长分析了一下,我这个分数还有一点点省选翻盘的希望……那就试试吧!
这个在OIBH上发过,也很高兴大家能为我提出宝贵的意见和建议。这也是我能继续进步的基础。以后我会在这里发点菜鸟教程,希望能为各位初学者一点点帮助。至少能让你从不会敲代码进步到会敲代码。
这次修订版要一下的改动:
1. 高精度乘法中有一个错误。“>=”打成了“>”。
2. 增加了一个求快速幂。
3. 二路归并排序增加了求逆序对个数计为ans,同时也换了个风格。
十进制转换K进制 function dectok(x,k:longint):string; const alph='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; var st:string; begin st:=''; while x<>0 do begin st:=alph[x mod k+1]+st; x:=x div k; end; exit(st); end; K进制转换十进制 function ktodec(st:string; k:longint):longint; const alph='012456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; var i,j,ans:longint; begin ans:=0; j:=1; for i:=length(st) downto 1 do begin inc(ans,j*(pos(st[i],alph)-1)); j:=j*k; end; exit(ans); end; 欧几里得算法 function gcd(a,b:longint):longint; begin if b=0 then exit(a) else exit(gcd(b,a mod b)); end; 求最小公倍数 function lcm(a,b:longint):longint; begin exit(a div gcd(a,b) *b); end; 判断质数 function judgeprime(x:longint); var i:longint; begin if x=1 then exit(false); for i:=2 to trunc(sqrt(x)) do if x mod i=0 then exit(false); exit(true); end; 生成质数表 procedure makeprime; var i,j:longint; begin fillchar(f,sizeof(f),0); f[1]:=true; for i:=2 to n do if (not f[i]) and (i<10000) then begin j:=i*i; while j<=n do begin f[j]:=true; inc(j,i); end; end; end; 快速幂 function calc(x:qword):qword; begin if x=0 then exit(1); if x=1 then exit(2); if odd(x) then exit(2*sqr(calc((x-1) div 2)) mod p) else exit(sqr(calc(x div 2)) mod p); exit(calc(x div 2)*calc(x-x div 2) mod p); end; 简单高精度运算系列 procedure change(st:string; var x:array of longint); begin x[0]:=0; while length(st)>4 do begin inc(x[0]); val(copy(st,length(st)-3,4),x[x[0]]); delete(st,length(st)-3,4); end; inc(x[0]); val(st,x[x[0]]); end; function compare(a,b:array of longint):boolean; var i:longint; begin if a[0]>b[0] then exit(true); if a[0]<b[0] then exit(false); for i:=a[0] downto 1 do if a[i]>b[i] then exit(true) else if a[i]<b[i] then exit(false); exit(true); end; procedure highplus(a,b:array of longint; var c:array of longint); var i:longint; begin fillchar(c,sizeof(c),0); if a[0]>b[0] then c[0]:=a[0] else c[0]:=b[0]; for i:=1 to c[0] do inc(c[i],a[i]+b[i]); for i:=1 to c[0] do if c[i]>=10000 then begin dec(c[i],10000); inc(c[i+1]); end; while c[c[0]+1]>0 do inc(c[0]); end; procedure highminus(a,b:array of longint; var c:array of longint); var i:longint; begin fillchar(c,sizeof(c),0); c[0]:=a[0]; for i:=1 to c[0] do inc(c[i],a[i]-b[i]); for i:=1 to c[0] do if c[i]<0 then begin inc(c[i],10000); dec(c[i+1]); end; while (c[0]<>1)and(c[c[0]]=0) do dec(c[0]); end; procedure highmulti(a,b:array of longint; var c:array of longint); var i,j:longint; begin fillchar(c,sizeof(c),0); c[0]:=a[0]+b[0]-1; for i:=1 to a[0] do for j:=1 to b[0] do inc(c[i+j-1],a[i]*b[j]); for i:=1 to c[0] do if c[i]>=10000 then begin inc(c[i+1],c[i] div 10000); c[i]:=c[i] mod 10000; end; while c[c[0]+1]>0 do inc(c[0]); end; procedure highout(x:array of longint); var i:longint; begin write(x[x[0]]); for i:=x[0]-1 downto 1 do begin if x[i]<1000 then write(0); if x[i]<100 then write(0); if x[i]<10 then write(0); write(x[i]); end; writeln; end; 表达式求值 const num='0123456789'; sym='+-*/()@'; com:array[1..7,1..7] of longint=((1,1,-1,-1,-1,1,1), (1,1,-1,-1,-1,1,1), (1,1,1,1,-1,1,1), (1,1,1,1,-1,1,1), (-1,-1,-1,-1,-1,0,2), (1,1,1,1,2,1,1), (-1,-1,-1,-1,-1,2,0)); function calc(suf:string):double; var stack:array[1..100] of double; i,top:longint; x:double; ch:char; begin i:=1; ch:=suf[1]; top:=0; while ch<>'@' do begin case ch of '+': begin x:=stack[top-1]+stack[top]; dec(top,2); end; '-': begin x:=stack[top-1]-stack[top]; dec(top,2); end; '*': begin x:=stack[top-1]*stack[top]; dec(top,2); end; '/': begin x:=stack[top-1]/stack[top]; dec(top,2); end; '0'..'9': begin x:=0; while ch<>' ' do begin x:=x*10+pos(ch,num)-1; inc(i); ch:=suf[i]; end; end end; inc(top); stack[top]:=x; inc(i); ch:=suf[i]; end; exit(stack[top]); end; procedure turn(var mid,suf:string); var stack:array[1..100] of longint; i,top,w:longint; ch:char; begin mid:=mid+' @'; suf:=''; stack[1]:=7; i:=1; top:=1; ch:=mid[1]; while ch<>'@' do begin if pos(ch,num)<>0 then begin while pos(ch,num)<>0 do begin suf:=suf+ch; inc(i); ch:=mid[i]; end; suf:=suf+' '; end; if pos(ch,sym)<>0then begin w:=stack[top]; while com[w,pos(ch,sym)]=1 do begin suf:=suf+sym[w]; dec(top); w:=stack[top]; end; if com[w,pos(ch,sym)]=-1 then begin inc(top); stack[top]:=pos(ch,sym); end else dec(top); end; inc(i); ch:=mid[i]; end; w:=stack[top]; while w<>7 do begin suf:=suf+sym[w]; dec(top); w:=stack[top]; end; suf:=suf+'@'; end; 格拉汉扫除法 function direction(a,b,c:situ):real; begin exit((a.x-c.x)*(b.y-c.y)-(a.y-c.y)*(b.y-c.y)); end; function dist(a,b:situ):real; begin exit(sqrt(sqr(a.x-b.x)+sqr(a.y-b.y)); end; procedure polarangle(s,t:longint); var l,r:longint; key,tmp:situ; begin l:=s; r:=t; key:=p[random(t-s+1)+s]; while l<=r do begin while (direction(p[l],key,p[1])>0)or ((direction(p[l],key,p[1])=0)and(dist(p[l],p[1])<dist(key,p[1]))) do inc(l); while (direction(p[r],key,p[1])<0)or ((direction(p[r],key,p[1])=0)and(dist(p[r],p[1])>dist(key,p[1]))) do dec(r); if l<=r then begin tmp:=p[l]; p[l]:=p[r]; p[r]:=tmp; inc(l); dec(r); end; end; if s<r then qsort(s,r); if l<t then qsort(l,t); end; procedure getvex; var i:longint; tmp:situ; begin for i:=2 to n do if (p[i].y<p[1].y)or((p[i].y=p[1].y)and(p[i].x<p[1].x)) then begin tmp:=p[1]; p[1]:=p[i]; p[i]:=tmp; end; end; procedure graham; var i:longint; begin getvex; randomize; polarangle(2,n); stack[0]:=2; stack[1]:=1; stack[2]:=2; for i:=3 to n do begin while (stack[0]>1)and(direction(p[i],p[stack[stack[0]]],p[stack[stack[0]-1]])>=0) do dec(stack[0]); inc(stack[0]); stack[stack[0]]:=i; end; ans:=dist(p[stack[stack[0]]],p[stack[1]]); for i:=1 to stack[0]-1 do ans:=ans+dist(p[stack[i]],p[stack[i+1]]); end; 判断线段相交 function segment(a,b,c:situ):boolean; begin if (min(a.x,b.x)<=c.x)and(max(a.x,b.x)>=c.x)and (min(a.y,b.y)<=c.y)and(max(a.y,b.y)>=c.y) then exit(true); exit(false); end; function intersect(a,b,c,d:situ):boolean; var da,db,dc,dd:real; begin da:=direction(c,d,a); db:=direction(c,d,b); db:=direction(a,b,c); dd:=direction(a,b,d); if (da*db<-(1e-16)) and (dc*dd<-(1e-16)) then exit(true); if (abs(da)<1e-16) and segment(c,d,a) then exit(true); if (abs(db)<1e-16) and segment(c,d,b) then exit(true); if (abs(dc)<1e-16) and segment(a,b,c) then exit(true); if (abs(dd)<1e-16) and segment(a,b,d) then exit(true); exit(false); end; 弗洛伊德算法 procedure floyd; var i,j,k:longint; begin for i:=1 to n do for j:=1 to n do if g[i,j]<>0 then dist[i,j]:=g[i,j] else dist[i,j]:=maxlongint; for k:=1 to n do for i:=1 to n do for j:=1 to n do if (dist[i,k]<>maxlongint)and(dist[k,j]<>maxlongint)and (dist[i,k]+dist[k,j]<dist[i,j]) then dist[i,j]:=dist[i,k]+dist[k,j]; end; SPFA算法 procedure spfa(s:longint); var vis:array[1..100] of boolean; que:array[0..99] of longint; i,u,open,clo:longint; begin fillchar(vis,sizeof(vis),0); for i:=1 to n do dist[i]:=maxlongint; open:=0; clo:=1; dist[s]:=0; vis[s]:=true; que[1]:=s; while open<>clo do begin open:=(open+1) mod n; u:=que[open]; vis[u]:=false; for i:=1 to n do if (g[u,i]<>0) and (dist[u]+g[u,i]<dist[i]) then begin if not vis[i] then begin clo:=(clo+1) mod n; que[clo]:=u; vis[clo]:=true; end; dist[i]:=dist[u]+g[u,i]; end; end; end; 克鲁斯卡尔算法 procedure kruskal; var father:array[1..100] of longint; i,get:longint; function find(i:longint):longint; begin if father[i]=i then exit(i) else father[i]:=find(father[i]); exit(father[i]); end; procedure union(i,j:longint); var u,v:longint; begin v:=find(i); u:=find(j); father[v]:=u; end; begin qsort(1,e); get:=0; for i:=1 to n do father[i]:=i; for i:=1 to e do if find(edge[i].u)<>find(edge[i].v) then begin union(edge[i].u,edge[i].v); inc(ans,edge[i].data); inc(get); if get=n-1 then exit; end; end; Kosaraju算法 procedure kosaraju; var vis:array[1..100] of boolean; order:array[1..100] of longint; i,time:longint; procedure forthdfs(u:longint); var i:longint; begin vis[u]:=true; for i:=1 to n do if g[u,i] and (not vis[i]) then forthdfs(i); inc(time); order[time]:=u; end; procedure backdfs(u:longint); var i:longint; begin vis[u]:=true; for i:=1 to n do if g[i,u] and (not vis[i]) then backdfs(i); fill[u]:=color; end; begin fillchar(vis,sizeof(vis),0); time:=0; for i:=1 to n do if not vis[i] then forthdfs(i); fillchar(vis,sizeof(vis),0); color:=0; for i:=time downto 1 do if not vis[order[i]] then begin inc(color); backdfs(order[i]); end; end; 最短增广路算法 procedure sap(s,t:longint); var dist,dsum,nowvex,pre,data:array[0..100] of longint; i,j,delta,mintmp,minvex:longint; flag:boolean; begin fillchar(dist,sizeof(dist),0); for i:=1 to n do nowvex[i]:=1; dsum[0]:=n; delta:=maxlongint; i:=s; while dist[s]<n do begin flag:=false; data[i]:=delta; for j:=nowvex[i] to n do if (c[i,j]>0) and (dist[j]+1=dist[i]) then begin flag:=true; nowvex[i]:=j; pre[j]:=i; if delta>c[i,j] then delta:=c[i,j]; i:=j; if i=t then begin inc(maxflow,delta); while i<>s do begin dec(c[pre[i],i],delta); inc(c[i,pre[i]],delta); i:=pre[i]; end; i:=s; delta:=maxlongint; end; break; end; if flag then continue; dec(dsum[dist[i]]); if dsum[dist[i]]=0 then exit; mintmp:=n-1; for j:=1 to n do if (c[i,j]>0) and (dist[j]<mintmp) then begin mintmp:=dist[j]; minvex:=j; end; dist[i]:=mintmp+1; nowvex[i]:=minvex; inc(dsum[dist[i]]); if i<>s then i:=pre[i]; delta:=data[i]; end; end; 匈牙利算法 function hungary(s:longint):boolean; var i:longint; begin for i:=1 to m do if g[s,i] and (not vis[i]) then begin vis[i]:=true; if link[i]=0 then begin link[i]:=s; exit(true); end else if hungary(link[i]) then begin link[i]:=s; exit(true); end; end; exit(false); end; KM算法 function find(k:longint):longint; var i:longint; begin x[k]:=true; for i:=1 to n do if (not y[i]) and (lx[k]+ly[i]=g[k,i]) then begin y[i]:=true; if link[i]=0 then begin link[i]:=k; exit(true); end else if find(link[i]) then begin link[i]:=k; exit(true); end; end; exit(false); end; procedure km; var i,j,k,d:longint; begin fillchar(lx,sizeof(lx),0); fillchar(ly,sizeof(ly),0); for i:=1 to n do for j:=1 to n do if g[i,j]>lx[i] then lx[i]:=g[i,j]; for k:=1 to n do repeat fillchar(x,sizeof(x),0); fillchar(y,sizeof(y),0); if find(k) then break; d:=maxlongint; for i:=1 to n do if x[i] then for j:=1 to n do if not y[j] then if lx[i]+ly[j]-g[i,j]<d then d:=lx[i]+ly[j]-g[i,j]; for i:=1 to n do begin if x[i] then dec(lx[i],d); if y[i] then inc(ly[i],d); end; until false; end;
- 基础代码汇总整理 for NOIP 2009 修订版(上)
- 基础代码汇总整理 for NOIP 2009 修订版(下)
- 【个人整理】NOIP知识点汇总
- NOIP知识汇总及模板整理
- Noip复习 图论代码整理
- NOIP 2009 题解+代码
- 单片机程序设计基础(修订版)
- 【个人网络整理】NOIP / 省选 /NOI 知识点汇总
- 女人 Vs 程序语言[整理/修订版]
- JAVA 代码基础规范汇总
- 代码检查 整理汇总(一)
- 托业词汇汇总(修订版)
- SQL server基础代码整理
- c基础部分代码整理
- css基础代码库整理
- Java基础整理-多线程基础(上)
- 正则表达式必知必会(修订版)整理教程
- 【NOIP 2015】总结汇总
- Flex 中利用Matrix 类的rotate函数对图片进行旋转操作的例子
- "RemoteOperationException: ERROR: Wrong password for user"错误 解决方案
- 初步尝试WPF
- CArray的使用
- C#中自定义消息传送数组
- 基础代码汇总整理 for NOIP 2009 修订版(上)
- malloc/free 和new/delete总结
- RTP的FAQ
- SoapUI Knowledge sharing
- DB2 OLAP函数的使用
- JS去空格
- 俄罗斯方块
- 脏读 不可重复读 幻像(幻觉读)
- va_list