基础代码汇总整理 for NOIP 修订版.docx
《基础代码汇总整理 for NOIP 修订版.docx》由会员分享,可在线阅读,更多相关《基础代码汇总整理 for NOIP 修订版.docx(33页珍藏版)》请在冰豆网上搜索。
![基础代码汇总整理 for NOIP 修订版.docx](https://file1.bdocx.com/fileroot1/2022-11/22/c16cf937-78cd-4943-ab1d-e0b934ee25db/c16cf937-78cd-4943-ab1d-e0b934ee25db1.gif)
基础代码汇总整理forNOIP修订版
基础代码汇总整理forNOIP2009修订版(上)
修订版序言
NOIP2009出乎意料地死掉了。
不能说没有没发挥出来的地方,但我确实可能还有很多需要完善的地方。
也许是自以为省一已经是囊中之物,有些不知天高地厚了吧!
不过既然已经努力过了我也就没什么遗憾了。
跟我的学长分析了一下,我这个分数还有一点点省选翻盘的希望……那就试试吧!
这个在OIBH上发过,也很高兴大家能为我提出宝贵的意见和建议。
这也是我能继续进步的基础。
以后我会在这里发点菜鸟教程,希望能为各位初学者一点点帮助。
至少能让你从不会敲代码进步到会敲代码。
这次修订版要一下的改动:
1. 高精度乘法中有一个错误。
“>=”打成了“>”。
2. 增加了一个求快速幂。
3. 二路归并排序增加了求逆序对个数计为ans,同时也换了个风格。
十进制转换K进制
functiondectok(x,k:
longint):
string;
constalph='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
varst:
string;
begin
st:
='';
whilex<>0do
begin
st:
=alph[xmodk+1]+st;
x:
=xdivk;
end;
exit(st);
end;
K进制转换十进制
functionktodec(st:
string;k:
longint):
longint;
constalph='012456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
vari,j,ans:
longint;
begin
ans:
=0;
j:
=1;
fori:
=length(st)downto1do
begin
inc(ans,j*(pos(st[i],alph)-1));
j:
=j*k;
end;
exit(ans);
end;
欧几里得算法
functiongcd(a,b:
longint):
longint;
begin
ifb=0thenexit(a)
elseexit(gcd(b,amodb));
end;
求最小公倍数
functionlcm(a,b:
longint):
longint;
begin
exit(adivgcd(a,b)*b);
end;
判断质数
functionjudgeprime(x:
longint);
vari:
longint;
begin
ifx=1thenexit(false);
fori:
=2totrunc(sqrt(x))do
ifxmodi=0then
exit(false);
exit(true);
end;
生成质数表
proceduremakeprime;
vari,j:
longint;
begin
fillchar(f,sizeof(f),0);
f[1]:
=true;
fori:
=2tondo
if(notf[i])and(i<10000)then
begin
j:
=i*i;
whilej<=ndo
begin
f[j]:
=true;
inc(j,i);
end;
end;
end;
快速幂
functioncalc(x:
qword):
qword;
begin
ifx=0thenexit
(1);
ifx=1thenexit
(2);
ifodd(x)thenexit(2*sqr(calc((x-1)div2))modp)
elseexit(sqr(calc(xdiv2))modp);
exit(calc(xdiv2)*calc(x-xdiv2)modp);
end;
简单高精度运算系列
procedurechange(st:
string;varx:
arrayoflongint);
begin
x[0]:
=0;
whilelength(st)>4do
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;
functioncompare(a,b:
arrayoflongint):
boolean;
vari:
longint;
begin
ifa[0]>b[0]thenexit(true);
ifa[0]
fori:
=a[0]downto1do
ifa[i]>b[i]thenexit(true)
elseifa[i]
exit(true);
end;
procedurehighplus(a,b:
arrayoflongint;varc:
arrayoflongint);
vari:
longint;
begin
fillchar(c,sizeof(c),0);
ifa[0]>b[0]thenc[0]:
=a[0]
elsec[0]:
=b[0];
fori:
=1toc[0]do
inc(c[i],a[i]+b[i]);
fori:
=1toc[0]do
ifc[i]>=10000then
begin
dec(c[i],10000);
inc(c[i+1]);
end;
whilec[c[0]+1]>0doinc(c[0]);
end;
procedurehighminus(a,b:
arrayoflongint;varc:
arrayoflongint);
vari:
longint;
begin
fillchar(c,sizeof(c),0);c[0]:
=a[0];
fori:
=1toc[0]do
inc(c[i],a[i]-b[i]);
fori:
=1toc[0]do
ifc[i]<0then
begin
inc(c[i],10000);
dec(c[i+1]);
end;
while(c[0]<>1)and(c[c[0]]=0)dodec(c[0]);
end;
procedurehighmulti(a,b:
arrayoflongint;varc:
arrayoflongint);
vari,j:
longint;
begin
fillchar(c,sizeof(c),0);c[0]:
=a[0]+b[0]-1;
fori:
=1toa[0]do
forj:
=1tob[0]do
inc(c[i+j-1],a[i]*b[j]);
fori:
=1toc[0]do
ifc[i]>=10000then
begin
inc(c[i+1],c[i]div10000);
c[i]:
=c[i]mod10000;
end;
whilec[c[0]+1]>0doinc(c[0]);
end;
procedurehighout(x:
arrayoflongint);
vari:
longint;
begin
write(x[x[0]]);
fori:
=x[0]-1downto1do
begin
ifx[i]<1000thenwrite(0);
ifx[i]<100thenwrite(0);
ifx[i]<10thenwrite(0);
write(x[i]);
end;
writeln;
end;
表达式求值
constnum='0123456789';
sym='+-*/()@';
com:
array[1..7,1..7]oflongint=((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));
functioncalc(suf:
string):
double;
varstack:
array[1..100]ofdouble;
i,top:
longint;
x:
double;
ch:
char;
begin
i:
=1;ch:
=suf[1];top:
=0;
whilech<>'@'do
begin
casechof
'+':
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;
whilech<>''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;
procedureturn(varmid,suf:
string);
varstack:
array[1..100]oflongint;
i,top,w:
longint;
ch:
char;
begin
mid:
=mid+'@';suf:
='';
stack[1]:
=7;
i:
=1;top:
=1;
ch:
=mid[1];
whilech<>'@'do
begin
ifpos(ch,num)<>0then
begin
whilepos(ch,num)<>0do
begin
suf:
=suf+ch;
inc(i);
ch:
=mid[i];
end;
suf:
=suf+'';
end;
ifpos(ch,sym)<>0then
begin
w:
=stack[top];
whilecom[w,pos(ch,sym)]=1do
begin
suf:
=suf+sym[w];
dec(top);
w:
=stack[top];
end;
ifcom[w,pos(ch,sym)]=-1then
begin
inc(top);
stack[top]:
=pos(ch,sym);
end
else
dec(top);
end;
inc(i);
ch:
=mid[i];
end;
w:
=stack[top];
whilew<>7do
begin
suf:
=suf+sym[w];
dec(top);
w:
=stack[top];
end;
suf:
=suf+'@';
end;
格拉汉扫除法
functiondirection(a,b,c:
situ):
real;
begin
exit((a.x-c.x)*(b.y-c.y)-(a.y-c.y)*(b.y-c.y));
end;
functiondist(a,b:
situ):
real;
begin
exit(sqrt(sqr(a.x-b.x)+sqr(a.y-b.y));
end;
procedurepolarangle(s,t:
longint);
varl,r:
longint;
key,tmp:
situ;
begin
l:
=s;r:
=t;key:
=p[random(t-s+1)+s];
whilel<=rdo
begin
while(direction(p[l],key,p[1])>0)or
((direction(p[l],key,p[1])=0)and(dist(p[l],p[1])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])))dodec(r);
ifl<=rthen
begin
tmp:
=p[l];
p[l]:
=p[r];
p[r]:
=tmp;
inc(l);
dec(r);
end;
end;
ifsiflend;
proceduregetvex;
vari:
longint;
tmp:
situ;
begin
fori:
=2tondo
if(p[i].y
begin
tmp:
=p[1];
p[1]:
=p[i];
p[i]:
=tmp;
end;
end;
proceduregraham;
vari:
longint;
begin
getvex;
randomize;
polarangle(2,n);
stack[0]:
=2;
stack[1]:
=1;
stack[2]:
=2;
fori:
=3tondo
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]]);
fori:
=1tostack[0]-1doans:
=ans+dist(p[stack[i]],p[stack[i+1]]);
end;
判断线段相交
functionsegment(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;
functionintersect(a,b,c,d:
situ):
boolean;
varda,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))thenexit(true);
if(abs(da)<1e-16)andsegment(c,d,a)thenexit(true);
if(abs(db)<1e-16)andsegment(c,d,b)thenexit(true);
if(abs(dc)<1e-16)andsegment(a,b,c)thenexit(true);
if(abs(dd)<1e-16)andsegment(a,b,d)thenexit(true);
exit(false);
end;
弗洛伊德算法
procedurefloyd;
vari,j,k:
longint;
begin
fori:
=1tondo
forj:
=1tondo
ifg[i,j]<>0thendist[i,j]:
=g[i,j]
elsedist[i,j]:
=maxlongint;
fork:
=1tondo
fori:
=1tondo
forj:
=1tondo
if(dist[i,k]<>maxlongint)and(dist[k,j]<>maxlongint)and
(dist[i,k]+dist[k,j]dist[i,j]:
=dist[i,k]+dist[k,j];
end;
SPFA算法
procedurespfa(s:
longint);
varvis:
array[1..100]ofboolean;
que:
array[0..99]oflongint;
i,u,open,clo:
longint;
begin
fillchar(vis,sizeof(vis),0);
fori:
=1tondodist[i]:
=maxlongint;
open:
=0;clo:
=1;
dist[s]:
=0;vis[s]:
=true;que[1]:
=s;
whileopen<>clodo
begin
open:
=(open+1)modn;
u:
=que[open];
vis[u]:
=false;
fori:
=1tondo
if(g[u,i]<>0)and(dist[u]+g[u,i]begin
ifnotvis[i]then
begin
clo:
=(clo+1)modn;
que[clo]:
=u;
vis[clo]:
=true;
end;
dist[i]:
=dist[u]+g[u,i];
end;
end;
end;
克鲁斯卡尔算法
procedurekruskal;
varfather:
array[1..100]oflongint;
i,get:
longint;
functionfind(i:
longint):
longint;
begin
iffather[i]=ithenexit(i)
elsefather[i]:
=find(father[i]);
exit(father[i]);
end;
procedureunion(i,j:
longint);
varu,v:
longint;
begin
v:
=find(i);
u:
=find(j);
father[v]:
=u;
end;
begin
qsort(1,e);
get:
=0;
fori:
=1tondofather[i]:
=i;
fori:
=1toedo
iffind(edge[i].u)<>find(edge[i].v)then
begin
union(edge[i].u,edge[i].v);
inc(ans,edge[i].data);
inc(get);
ifget=n-1thenexit;
end;
end;
Kosaraju算法
procedurekosaraju;
varvis:
array[1..100]ofboolean;
order:
array[1..100]oflongint;
i,time:
longint;
procedureforthdfs(u:
longint);
vari:
longint;
begin
vis[u]:
=true;
fori:
=1tondo
ifg[u,i]and(notvis[i])then
forthdfs(i);
inc(time);
order[time]:
=u;
end;
procedurebackdfs(u:
longint);
vari:
longint;
begin
vis[u]:
=true;
fori:
=1tondo
ifg[i,u]and(notvis[i])then
backdfs(i);
fill[u]:
=color;
end;
begin
fillchar(vis,sizeof(vis),0);
time:
=0;
fori:
=1tondo
ifnotvis[i]then
forthdfs(i);
fillchar(vis,sizeof(vis),0);
color:
=0;
fori:
=timedownto1do
ifnotvis[order[i]]then
begin
inc(color);
backdfs(order[i]);
end;
end;
最短增广路算法
proceduresap(s,t:
longint);
vardist,dsum,nowvex,pre,data:
array[0..100]oflongint;
i,j,delta,mintmp,minvex:
longint;
flag:
boolean;
begin
fillchar(dist,sizeof(dist),0);
fori:
=1tondonowvex[i]:
=1;
dsum[0]:
=n;delta:
=maxlongint;i:
=s;
whiledist[s]begin
flag:
=false;data[i]:
=delta;
forj:
=nowvex[i]tondo
if(c[i,j]>0)and(dist[j]+1=dist[i])then
begin
flag:
=true;
nowvex[i]:
=j;
pre[j]:
=i;
ifdelta>c[i,j]thendelta:
=c[i,j];
i:
=j;
ifi=tthen
begin
inc(maxflow,de