总结
procedure dfs(x); var begin if 达到目标状态 then 输出结果并退出过程; if 满足剪枝条件 then exit; for i:=1 to 搜索宽度 do begin 备份现场;(注意如果现场使用了全局变量,则需要使用局部变量备份) dfs(参数+增量); 恢复现场; end;
初始化;把初始布局存入 设首指针head=0; 尾指针tail:=1; Repeat Inc(head),取出队列首记录为当前被扩展结点; For i:=1 to 规则数 do {r是规则编号} Begin If 新空格位置合法 then Begin If 新布局与队列中原有记录不重复 tail增1,并把新布局存入队尾; if 达到目标 then 输出并退出; End; End; Until head>=tail; {队列空}
var a:array[1..100] of longint;t,n,i,j:longint; procedure sort; begin for i:=1 to n-1 do{与每个数都进行比较} for j:=1 to n-i do if a[j]>a[j+1] then begin t:=a[j]; a[j]:=a[j+1]; a[j+1]:=t; end; end;
var a:array[1..100] of longint;t,n,i,j:longint; procedure sort; begin for i:=1 to n-1 do for j:=1+i to n do{大数沉小数浮} if a[j]>a[i] then begin t:=a[j]; a[j]:=a[i]; a[i]:=t; end; end;
var a:array[0..100] of longint;n,i,j,t:longint; procedure sort; begin for i:=2 to n do for j:=1 to (i-1) do begin if (a[i]<a[j]) then begin t:=a[j]; a[j]:=a[i]; a[i]:=t; end; end; end;
var a,b:array[0..100] of longint;r,i,j,t,k,n:longint; procedure sort; begin for i:=0 to 100 do b[i]:=0;{为B数组清零,小桶内容清零} for i:=1 to n do b[a[i]]:=b[a[i]]+1; {桶的序号就是那个要排序的东西;出现一次,桶里得旗数加一} for i:=0 to 100 do{扫描所有的桶} begin if b[i]<>0 then{桶里有旗} for j:=1 to b[i] do write(i,' ');{桶的序号就是那个数} end; end;
var a:array[1..100] of longint; n,i,h,g:longint; procedure kp(l,r:longint);{变量不能与全局变量相同,否则会被抹去} var b,m,i,j,t:longint; begin i:=l; j:=r; m:=a[(l+r) div 2];{基准数最好从中间取} repeat while a[j]>m do dec(j); while a[i]<m do inc(i);{两侧的哨兵移动} if i<=j then {哨兵未碰面}{“=”利用repeat循环的性质,使repeat循环得以结束} begin t:=a[j]; a[j]:=a[i a[i]:=t;{交换两个哨兵的值} inc(j); dec(j);{哨兵继续运动} end; until i>j; if j>l then kp(l,j); if i<r then kp(i,r);{都是循环不结束后进行的动作} end; begin read(n); for i:=1 to n do read(a[i]); kp(1,n); {“一”位置与“N”位置} for i:=1 to n-1 do write(a[i],' '); write(a[n]);{防止多输出空格使程序结果出错} end.
var a:array[1..100] of longint; n,i,b:longint; procedure jianshu(i:longint); begin while ((a[i]>a[i*2])or(a[i]>a[i*2+1]))and(i<=n div 2) do {当父亲数大于子女数时并且他有孩子时进行} begin if a[i*2]<=a[i*2+1]{左儿子小于右儿子} then begin b:=a[i*2]; a[i*2]:=a[i];a[i]:=b;{左右儿子的值互换} jianshu(i*2);{继续为左儿子建树} end else begin b:=a[i*2+1];a[i*2+1]:=a[i];a[i]:=b; jianshu(i*2+1);{上同,不过是为右儿子建树} end; end; end; procedure tiao; begin while n<>0 do begin write(a[1]); a[1]:=a[n]; n:=n-1; for i:=(n div 2) downto 1 do jianshu(i); end; end; begin read(n); for i:=1 to n do read(a[i]); for i:=(n div 2) downto 1 do jianshu(i); tiao; end.
function gcd(a,b:longint):longint; begin if b=0 then gcd:=a else gcd:=gcd (b,a mod b); end ;
function lcm(a,b:longint):longint; begin if a<b then swap(a,b); lcm:=a; while lcm mod b>0 do inc(lcm,a); end;
function prime (n: longint): boolean; var i longint; begin for i:=2 to trunc(sqrt(n)) do if n mod i=0 then exit(false) exit(true); end;
procedure main; var i,j:longint; begin fillchar(f,sizeof(f),true); f[0]:=false;f[1]:=false; for i:=2 to trunc(sqrt(maxn)) do if f[i] then begin j:=2*i; while j<= maxn do begin f[j]:=false; inc(j,i); end; end; end;
{a^b mod n}
function f(a,b,n:int64):int64;
var t,y:int64;
begin
t:=1;
y:=a;
while b<>0 do
begin
if(b and 1)=1 then t:=t*y mod n;
y:=y*y mod n;
{这里用了一个很强大的技巧,y*y即求出了a^(2^(i-1))不知道这是什么的看原理}
b:=b shr 1;{去掉已经处理过的一位}
end;
exit(t);
end;
var a:array[1..1000] of longint; m,n,i,j,sum:longint; weizhi:longint=0; begin readln(m,n); for i:=1 to m do a[i]:=i; sum:=m; repeat weizhi:=weizhi+1; if weizhi>m then weizhi:=weizhi-m; if a[weizhi]<>0 then begin j:=j+1; if j=n then begin a[weizhi]:=0; j:=0; sum:=sum-1; end; end; until sum=1; for i:=1 to m do if a[i]<>0 then write(a[i]); end.
h[0]:=1; h[1]:=1; for i:=2 to n do begin j:=i-1; k:=0; while k<>i do begin h[i]:=h[i]+h[k]*h[j]; dec(j); inc(k); end; end;
function extended-gcd(a, b:longint; var x, y:integer); var x1, y1 :integer; begin if b=0 then begin extended-gcd:=a; x:=1; y:=0 end else begin extended-gcd:=extended-gcd(b, a mod b, x1, y1); x:=y1; y:=x1-(a div b)*y1; end; end;
var a:array[1..100,1..100]of longint;p:array[1..100] of boolean;m,n,j:longint; procedure init; var i,x,y:longint; begin readln(n);readln(m); for i:=1 to m do begin read(x,y);a[x,y]:=1;a[y,x]:=1; end; end; procedure dfs(k:longint); var i:longint; begin write(k,' ');p[k]:=true; for i:=1 to m do if ((p[i]=false)and(a[k,i]=1)) then dfs(i);{k(i)是具体的点} end; begin fillchar(p,sizeof(p),false); init; dfs(1); end.
var a:array[1..100] of longint; closed:longint=1; open:longint=0; t:array [1..100,1..100] of longint; p:array [1..100]of boolean; j,n,m,g:longint; procedure add(x:longint); begin inc(closed); a[closed]:=x; end; function del:longint; begin inc(open); del:=a[open]; end; procedure init; var i,x,y:longint; begin readln(n); readln(m); for i:=1 to m do begin read(x,y); t[x,y]:=1; t[y,x]:=1; end; end; procedure bfs(j:longint); var i,k:longint; begin a[1]:=(j); write(j,' '); p[j]:=true; while open<closed do begin inc(open); k:=a[open]; for i:=1 to n do if ((p[i]=false)and(t[k,i]=1)) then begin write(i,' '); p[i]:=true; inc(closed); a[closed]:=i; end; end; end; begin for g:=1 to m do begin p[g]:=false; a[g]:=0; end; init; bfs(1); end.
var a:array[1..100,1..100]of integer;//邻接矩阵 flag:array[1..100] of boolean;//已经找到最短路径的节点标志 path:array[1..100]of integer; w,x,n,i,j,min,minn,k:integer; begin readln(n,k); for i:=1 to n do//读取邻接矩阵,无路径写-1 begin for j:=1 to n do begin read(a[i,j]); If a[i,j]=-1 then a[I,j]:=maxint; End; readln; end; fillchar(flag,sizeof(flag),false);//标明所有节点都未找到最短路径 flag[k]:=true; //源节点除外 fillword(path,sizeof(path) div 2,k); path[k]:=0; minn:=k;//标记最小的点 for x:=2 to n do begin min:=32767;//标记要找下一个最短路径点的距离 for i:=1 to n do//找下一点点 if (a[k,i]<min) and (flag[i]=false) then begin min:=a[k,i]; minn:=i; end; flag[minn]:=true;//标记下一个点的找到 for j:=1 to n do //更新最短路径 if (j<>minn) and (a[k,minn]+a[minn,j]<a[k,j]) and (flag[j]=false) then begin a[k,j]:=a[k,minn]+a[minn,j]; path[j]:=minn; end; end; for i:=1 to n do write(a[k,i],' ');//输出源点到各个点的距离 writeln; for i:=1 to n do write(path[i],' ');//输出源点到各个点的距离 end.
var st,en,f:integer; k,n,i,j,x:integer; a:array[1..10,1..10] of integer;//邻接矩阵 path:array[1..10,1..10] of integer;//path[a,b]为A点到B点的最短路径要走的第一个点 begin readln(n);//读取节点数 for i:=1 to n do//读取邻接矩阵 begin for j:=1 to n do begin read(k); if k<>0 then a[i,j]:=k else a[i,j]:=maxint; path[i,j]:=j; end; readln; end; for x:=1 to n do//I,J点之间加入X点,判断是否更短,并更新。 for i:=1 to n do for j:=1 to n do if a[i,j]>a[i,x]+a[x,j] then begin a[i,j]:=a[i,x]+a[x,j]; path[i,j]:=path[i,x]; end; readln(st,en);//读取开始结束点 writeln(a[st,en]);//写出开始结束长度 f:=st; while f<> en do//写出路径 begin write(f); write('-->'); f:=path[f,en]; end; writeln(en); end.
const maxp=10000;{最大结点数} maxv=100000;{最大边数} var p,c,s,t:longint;{p,结点数;c,边数;s:起点;t:终点} a,b:array[1..maxp,0..maxp]of longint; {a[x,y]存x,y之间边的权;b[x,c]存与x相连的第c个边的另一个结点y} d:array[1..maxp]of integer;{队列} v:array[1..maxp]of boolean;{是否入队的标记} // rn:array[1..maxp]of integer;{各个点的入队次数} dist:array[1..maxp]of longint;{到起点的最短路} head,tail:longint;{队首/队尾指针} procedure init; var i,x,y,z:longint; begin read(p,c); for i:=1 to c do begin readln(x,y,z); {x,y:一条边的两个结点;z:这条边的权值} inc(b[x,0]);b[x,b[x,0]]:=y;a[x,y]:=z; {b[x,0]:以x为一个结点的边的条数,b[x,a]:x点连接的第A个节点} inc(b[y,0]);b[y,b[y,0]]:=x;a[y,x]:=z;{无向图的操作,取舍} end; readln(s,t); end; procedure spfa(s:longint); var i,j,now,sum:longint; begin fillchar(d,sizeof(d),0); fillchar(v,sizeof(v),false); for j:=1 to p do dist[j]:=maxlongint; dist[s]:=0; v[s]:=true; d[1]:=s; // rn[s]:=1; {队列的初始状态,s为起点} head:=1;tail:=1; while head<=tail do{队列不空,注意:此处head>tial未空} begin now:=d[head]; for i:=1 to b[now,0]do{now指向的所有节点} if dist[b[now,i]]>dist[now]+a[now,b[now,i]]then {如果最短路径大于now节点的最短路径和now节点到该节点的路径之和} begin dist[b[now,i]]:=dist[now]+a[now,b[now,i]];{修改最短路} if not v[b[now,i]]then{扩展结点入队——如果此节点尚未入队,则入队,且表示} begin inc(tail); d[tail]:=b[now,i]; v[b[now,i]]:=true; // inc(rn[b[now,i]]); // if rn[b[now,i]]>c then begin writeln('fu huan');halt; end; end; end; v[now]:=false;{释放结点,一定要释放掉,因为这节点有可能下次用来松弛其它节点} inc(head); end; end; procedure print; begin writeln(dist[t]); end; begin init; spfa(s); print; end.
const max=1000; var map:array[1..MXN,1..MXN] of longint; cost:array[1..MXN] of longint; visit:array[1..MXN] of boolean; i,j,n,m,x,y,v:longint; function prim():longint; var i,j,min,mini,ans:longint; begin ans:=0; for i:=1 to n do begin visit[i]:=false;cost[i]:=maxlongint;end; //visit[i]是i点是否被访问的标志,cost[i]是到i点的最小权边。 for i:=2 to n do if map[1,i]<>0 then cost[i]:=map[1,i];visit[1]:=true; for i:=1 to n-1 do begin min:=maxlongint; for j:=1 to n do if not visit[j] and (cost[j]<min) then begin min:=cost[j];mini:=j;end; visit[mini]:=true;inc(ans,min); for j:=1 to n do if not visit[j] and (map[mini,j]>0) and (map[mini,j]<cost[j]) then cost[j]:=map[mini,j]; //更新圈内圈外存储的最短距离 end; exit(ans); end; begin readln(n,m); for i:=1 to m do begin readln(x,y,v); if (map[x,y]=0) or (map[x,y]>v) then begin map[x,y]:=v;map[y,x]:=v; end; end; writeln(prim()); end.
const MXN=1000; type rqmap=record s,t,v:longint; end; var map:array[1..MXN*MXN] of rqmap; father:array[1..MXN] of longint; n,m,i,ingraph,ans:longint; procedure qsort(b,e:longint);//排序 var i,j,x:longint; t:rqmap; begin i:=b;j:=e;x:=map[(i+j)>>1].v; while (i<=j) do begin while (map[i].v<x) do inc(i); while (map[j].v>x) do dec(j); if (i<=j) then begin t:=map[i];map[i]:=map[j];map[j]:=t;inc(i);dec(j);end; end; if i<e then qsort(i,e); if j>b then qsort(b,j); end; function find(x:longint):longint; begin if (father[x]=x) then exit(x); father[x]:=find(father[x]);//路径压缩 exit(father[x]); end; procedure union(a,b:longint); //并查集 begin father[find(a)]:=find(father[b]); end; begin readln(n,m); for i:=1 to n do father[i]:=i; for i:=1 to m do readln(map[i].s,map[i].t,map[i].v); qsort(1,m);ans:=0;ingraph:=1;i:=0; while (ingraph<n) do begin inc(i); if find(map[i].s)<>find(map[i].t) then begin inc(ingraph);inc(ans,map[i].v);union(map[i].s,map[i].t); end; end; writeln(ans); end.
const maxx=50; var a:array[1..maxx,1..maxx]of longint;//邻接矩阵 p:array[1..maxx] of longint;//拓扑路径 b:array[1..maxx] of longint;//b[i]表示第i个点到起点的距离 c:array[1..maxx] of longint;//c[i]表示在关键路径时i点的前驱 pd:array[1..maxx] of boolean; n,m,i,j,k:longint; procedure change; var i,j:longint; begin fillchar(a,sizeof(p),0); fillchar(b,sizeof(b),0); fillchar(c,sizeof(c),0); fillchar(p,sizeof(p),0); fillchar(pd,sizeof(pd),false); end; procedure tp(k:longint); var i,j:longint; begin if k=n+1 then exit; for i:=1 to n do begin if (b[i]=0) and (pd[i]) then begin p[k]:=i;//拓扑序列 pd[i]:=false; for j:=1 to n do if a[i,j]<>0 then dec(b[j]);//b[j] 用来存入度 tp(k+1); end; end; end; procedure main; var i,j:longint; begin b[p[1]]:=0; c[p[1]]:=0; for i:=2 to n do for j:=1 to n do if b[p[j]]+a[p[j],p[i]]>b[p[i]] then begin b[p[i]]:=b[p[i]]+a[p[j],p[i]]; c[p[i]]:=p[j]; end; end; procedure output; var i:longint; begin for i:=1 to n-1 do write(c[i],'-->'); writeln(c[n]); writeln(b[n]); end; begin change; readln(n); for i:=1 to n do for j:=1 to n do read(a[i,j]); tp(1); main; output; end.
const maxx=100; var a:array[1..maxx,1..maxx] of longint; et,eet:array[1..maxx] of longint; //eet表示活动最早可以开始的时间,et表示活动最迟应该开始的时间 n,i,j,k,x,y,w:longint; min,max:longint; begin fillchar(a,sizeof(a),char(-1)); fillchar(et,sizeof(et),0); fillchar(eet,sizeof(eet),0); readln(n); readln(x,y,w); while x<>0 do begin a[x,y]:=w; readln(x,y,w); end; eet[1]:=0; for i:=2 to n do begin max:=0; for j:=1 to n do if a[j,i]<>-1 then if a[j,i]+eet[j]>max then max:=a[j,i]+eet[j]; eet[i]:=max; end; et[n]:=eet[n]; for i:=n-1 downto 1 do//最迟开始时间需要倒着推 begin min:=maxint; for j:=1 to n do if et[j]-a[i,j]<min then//事件vi的最晚发生时间为:在不拖延整个工期的条件下,vi的可能的最晚发生时间。即ltv(i) = etv(n) - cp(i, n) min:=et[j]-a[i,j]; if a[i,j]<>-1 then et[i]:=min; end; for i:=1 to n-1 do if et[i]=eet[i] then //如果最早开始时间和最晚开始时间相同即认为是关键事件 write(i,'-->'); writeln(n); writeln(max); end. //默认为节点按顺序输入,即序号前面的结点会影响序号后面结点的活动
var a:array[1..100,1..100] of longint; s:array[1..100] of longint; ans:array[1..100] of longint; i,j,n,kg,x,w:longint; begin readln(n); fillchar(a,sizeof(a),0); fillchar(s,sizeof(s),0); for i:=1 to n do for j:=1 to n do begin read(a[i,j]); end; i:=1; x:=1; for j:=1 to n do begin kg:=0; for w:=1 to n do if a[w,j]=1 then inc(kg); if kg=0 then begin ans[x]:=j; inc(x); for w:=1 to n do a[j,w]:=0; end; end; for i:=1 to n do write(ans[i],' '); end.
var n,m,i,u,v,sum1,sum2,mid:longint; b,f:array[0..1010] of longint; procedure intt; begin assign(input,'draw.in'); assign(output,'draw.out'); reset(input); rewrite(output); end; procedure outt; begin close(input); close(output); end; procedure sort(l,r: longint); var i,j,x,y: longint; begin i:=l; j:=r; x:=f[(l+r) div 2]; repeat while f[i]<x do inc(i); while x<f[j] do dec(j); if not(i>j) then begin y:=f[i]; f[i]:=f[j]; f[j]:=y; y:=b[i]; b[i]:=b[j]; b[j]:=y; inc(i); j:=j-1; end; until i>j; if l<j then sort(l,j); if i<r then sort(i,r); end; function root(x:longint):Longint; begin if f[x]=x then exit(x) else root:=root(f[x]); f[x]:=root; exit(root); end; begin intt; readln(n,m); for i:=1 to n do f[i]:=i; for i:=1 to m do begin read(u,v); if root(u)<>root(v) then f[root(u)]:=root(v); inc(b[u]); inc(b[v]); end; for i:=1 to n do mid:=root(i); sort(1,n); v:=n; while v>1 do begin while f[v-1]<>f[v] do dec(v); inc(sum2); mid:=f[v]; while f[v]=mid do begin if b[v] mod 2=1 then inc(sum1); dec(v); end; if sum1>0 then sum1:=sum1-2; sum2:=sum2+sum1 div 2; sum1:=0; end; writeln((sum1 div 2)+sum2); outt; end.
var g:array[1..maxn,1..maxm]of boolean; //图,g[i,j]:节点i到节点j是否有边 y:array[1..maxm]of boolean; //访问标记,y[i]:节点i是否已被访问过 link:array[1..maxm]of longint; //与节点i匹配的点,link[i]=0 表示i没有被匹配 function find(v:longint):boolean; //从v出发找匹配 var i:longint; begin for i:=1 to m do //枚举与v相连的点i if g[v,i] and (not y[i]) then //如果i与v相连且还未被访问过 begin y[i]:=true; //标记i已被访问过 if (link[i]=0)or find(link[i]) then //如果i无匹配或原来的匹配点link[i]可以另找一个匹配 begin link[i]:=v; //让v-i与i匹配 find:=true; //匹配成功并返回 exit; end; end; find:=false; //匹配不成功 end; begin //read the graph into array g[][] for i:=1 to n do begin fillchar(y,sizeof(y),0); if find(i) then inc(ans); end; //now then ans stores the max match end.
var t,n,i:longint; begin while true do begin readln(n); if n=0 then halt; if n<=2 then writeln('Alice') else writeln('Bob'); end; end.
var x,y,n:int64;i:longint; procedure main; begin y:=0; read(n); for i:=1 to n do begin read(x); y:=y xor x; end; if y=0 then writeln('No') else writeln('Yes'); end; begin while not seekeof do main; end.
procedure hanoi(n,a,b,c:byte); {将第n块铜片从a柱通过b柱移到c柱上} begin if n=0 then exit; hanoi(n-1,a,c,b); {将上面的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;
type note=record father,lch,rch:longint;end; var a:array[1..100] of note;n,j,t,m:longint;s:longint; procedure duru; var i:longint;f,l,r:longint; begin read(n); for i:=1 to n do begin readln(f,l,r); a[f].lch:=l;{f的左孩子为l} a[f].rch:=r;{f的右孩子为r} if l<>0 then a[l].father:=f;{如果有左孩子那么左孩子的父亲是f} if r<>0 then a[r].father:=f;{如果有右孩子那么右孩子的父亲是f} end; end;{输入的过程,第一个是父亲,后两个为左右孩子,0表示空} function root:longint; var i:longint; begin for i:=1 to n do{i表示结点} if a[i].father=0 then begin root:=i;exit;{如果这个结点的父亲为零,则这个结点就是根} end; end;{找根的程序} procedure xiangen(t:longint); begin if t<>0 then begin write(t,' ');{先根} xiangen(a[t].lch);{再对左子树先根遍历,左孩子当根} xiangen(a[t].rch);{再对右子树先根遍历,后孩子当根} end; end;{进行先序遍历并输出的程序} begin duru;m:=root; writeln(m);xiangen(m); end.
procedure zhonggen(t:longint); begin if t<>0 then begin write(t,' '); zhonggen(a[t].lch); zhonggen(a[t].rch); end; end;
procedure hougen(t:longint); begin if t<>0 then begin hougen(a[t].lch); hougen(a[t].rch); write(t,' ') end; end;
var s1,s2:string; procedure work(s1,s2:string); var b,a:longint;{b,a的值在不断改变,必须放在局部变量里} begin if s1<>'' then begin b:=length(s1); a:=pos(s1[1],s2); work(copy(s1,2,a-1),copy(s2,1,a-1)); work(copy(s1,a+1,b-a),copy(s2,a+1,b-a)); write(s1[1]); end; end; begin readln(s1);readln(s2); work(s1,s2); end.
{已按秩优化} a:array[1..max] of longint;//a[i]表示i的前驱 function find(i:longint):longint;//非递归算法找i的根 var j,k,t:longint; begin j:=i; while a[j]<>0 do j:=a[j]; // 顺着i向上找根 find:=j; k:=i; //从i开始对子树结点进行路径压缩 while a[k]<>0 do begin t:=k;k:=a[k];a[t]:=j;end; end; function root(i:longint):longint;//递归算法找i的根 var j,k,t:longint; begin if a[i]=0 then exit(i); //若i为根,返回本身结点序号 root:=root(a[i]); //否则继续向上找 a[i]:=root; end; procedure union(x,y:longint);//合并 begin if root[x]=root[y] then else f[y]:=x; end;
{求2^k的代码:} function lowbit(t:longint):longint; begin lowbit:=t and(t xor (t-1)); end; {当想要查询一个SUM(n)(求A[1]..A[n]的和),可以依据如下算法即可: step1:令sum = 0,转第二步; step2:假如n <= 0,算法结束,返回sum值,否则sum = sum + Cn,转第三步; step3:令n = n–lowbit(n),转第二步。} function getsum(k:integer):integer; var t:integer; begin t:=0; while k>0 do begin t:=t+c[k]; k:=k-lowbit(k); end; getsum:=t; end; {修改算法如下(给某个结点i加上x): step1: 当i > n时,算法结束,否则转第二步; step2: Ci = Ci + x, i = i + lowbit(i)转第一步。 i = i +lowbit(i)这个过程实际上也只是一个把末尾1补为0的过程。} procedure add(i:longint;x:longint); begin while i<=n do begin c[i]:=C[i]+x; i:=i+lowbit(i); end; end;
type xtree=record a,b,left,right,cover:longint; end; //a,b是区间左右端点,当a=b表示一个叶子节点;left,right表示左右儿子,cover表示是否被覆盖 var tree:array[1..1000] of xtree; c,d,number,tot:longint; //tot为一共有多少个结点 procedure make(a,b:longint); var now:longint;//now必须为局部变量,dfs中枚举变量一样的道理 begin inc(tot); now:=tot; tree[now].a:=a; tree[now].b:=b; tree[now].cover:=0; if a+1<b then begin tree[now].left:=tot+1; make(a,(a+b)div 2); tree[now].right:=tot+1; //若now为全局变量,建左子树会修改now的值,导致此处建树不正确 make((a+b) div 2,b); end; end; //建树过程 procedure insert(num:longint); begin if (c<=tree[num].a)and(tree[num].b<=d) then inc(tree[num].cover) //若当前区间被[c,d]覆盖,则cover+1 else begin if c<(tree[num].a+tree[num].b)div 2 then insert(tree[num].left); if d>(tree[num].a+tree[num].b)div 2 then insert(tree[num].right); end; //否则将区间[c,d]插到左右子树中 end; //插入线段[c,d](c,d为全局变量)到线段树第num个节点区间 procedure delete(num:longint); begin if (c<=tree[num].a)and(tree[num].b<=d) then dec(tree[num].cover) //若当前区间被[c,d]覆盖,则cover-1 else begin if c<(tree[num].a+tree[num].b)div 2 then delete(tree[num].left); if d>(tree[num].a+tree[num].b)div 2 then delete(tree[num].right); end; //否则将区间[c,d]在左右子树中删除 end; //在线段树第num个节点区间中删除线段[c,d] procedure count(num:longint); begin if tree[num].cover>0 then number:=number+(tree[num].b-tree[num].a) //若当前区间被完全覆盖,则累加到number全局变量中 else begin if tree[num].left>0 then count(tree[num].left); if tree[num].right>0 then count(tree[num].right); end; //否则,若为部分覆盖,则累加左右子树的测度 end; //计算整个线段树的测度(被覆盖区间的总长度) begin readln(c,d); make(c,d); readln(c,d); insert(1);//插入线段[c,d]; readln(c,d); delete(1);//删除线段[c,d] count(1);//计算线段树的测度 writeln(number); end.
{treap示范代码: 标准的代码缩进风格,优美的算法实现。 经典标程,完全掌握后水平会提高很多 不改变bst的性质(在bst所有子树中均满足:左子树的所有节点<=根<=右子树的所有节点) 通过旋转操作,使根的hr最小(即所有的hr构成堆的关系)} var //l[i],r[i],v[i]:i号结点的左儿子、右儿子,关键值 //hr[i]:i号节点的优先值(treap所有子树中,根的hr必须是最小的) //s[i]:i号节点为根的子树节点总数 l,r,hr,s,v:array[0..2000000]of longint; n,root,m:longint; procedure init;//初始化 begin readln(n); m:=0; //randomize; //考试要求程序每次运行结果必须一致,慎用。确实要用:randomize 100; fillchar(s,sizeof(s),0); fillchar(l,sizeof(l),0); fillchar(r,sizeof(r),0); root:=0; end; //旋转是平衡二叉树的精髓,它不会改变bst的性质(左子树<=根<=右子树) //左旋使树的左子树深度+1,右子树深度-1 //右旋使树的右子树深度+1,左子树深度-1 procedure l_rotate(var x:longint);inline;//左旋以x为根的子树(注意var参数及意义) var y:longint; begin y:=r[x]; //保存x的右儿子到y中 r[x]:=l[y]; //将y的左儿子作为x的右儿子 l[y]:=x; //x作为y的左儿子 s[y]:=s[x]; //维护旋转后的子树大小 s[x]:=s[l[x]]+s[r[x]]+1; x:=y; //y为根 end; procedure r_rotate(var x:longint);inline;//右旋以x为根的子树 var y:longint; begin y:=l[x]; l[x]:=r[y]; r[y]:=x; s[y]:=s[x]; s[x]:=s[l[x]]+s[r[x]]+1; x:=y; end; //插入(递归,if key<=root,则插入到左子树,否则到右子树,直到尽头再新建节点) procedure insert(var k,key:longint);inline; begin if k=0 then//已到尽头,新建节点并写入key及随机值hr begin inc(m); v[m]:=key; s[m]:=1; hr[m]:=random(maxlongint); k:=m;//修改k,使父节点指向当前节点(修改前从父节点指向0) exit; end; inc(s[k]); if key<=v[k] then//若key<=根则插入到左子树,否则到右子树 begin insert(l[k],key);//若l[k]=0,到下层则新建节点并修改l[k]=m if hr[l[k]]>hr[k] then //旋转 r_rotate(k); exit; end; if key>v[k] then begin insert(r[k],key); if hr[r[k]]>hr[k] then l_rotate(k); exit; end; end; {删除:在k号节点为根的子树中删除key 基本方法:由于是静态结构,为了提高效率,并没真正删除 若找到则删除,若没找到,则删除查找尽头的节点 主程序中需判断返回值,若不等于key,重新插入key即可 找到后的处理: 若为叶节点,直接删除,否则,将要删除的节点左子树的最右节点(思考:为什么?)代替它 } function delete(var k:longint;key:longint):longint;inline; begin dec(s[k]);//维护节点总数 //如果找到,或已到尽头 if (key=v[k])or(l[k]=0)and(key<=v[k])or(r[k]=0)and(key>v[k]) then begin delete:=v[k];//返回要删除的节点(不一定=key) if (l[k]=0)or(r[k]=0) then //若左右子树只有一个,则让儿子代替根即可 begin k:=l[k]+r[k];//用儿子替换当前要删除的节点 exit; end; v[k]:=delete(l[k],key+1);//k左右子树都有,则用左子树的最右节点替换k exit; end; if key<=v[k] then//若k<=v[k],则在左子树中删,否则,在右子树中删 exit(delete(l[k],key)); if key>v[k] then exit(delete(r[k],key)); end; function find(var k,key:longint):boolean;inline;//查找 begin if k=0 then//递归边界 exit(false); if key>v[k] then find:=find(r[k],key) else find:=(v[k]=key)or find(l[k],key); end; //key的排名(key排在第几,按从小到大的顺序) function rank(var t,key:longint):longint;inline; begin if t=0 then exit(1); if key<=v[t] then rank:=rank(l[t],key) else rank:=s[l[t]]+1+rank(r[t],key); end; function select(var t:longint;k:longint):longint;inline;//选择排在第k位的数 begin if k=s[l[t]]+1 then//若找到第k位的节点,则返回节点key值 exit(v[t]); if k<=s[l[t]] then//递归 select:=select(l[t],k) else select:=select(r[t],k-1-s[l[t]]); end; function pred(var t,key:longint):longint;inline;//找key的前趋 begin if t=0 then exit(key); if key<=v[t] then//key<=根,原问题等价于在左子树中找key pred:=pred(l[t],key) else begin //key>根,原问题等价于在右子树中找key,但右儿子返回时,要判断你是不是key的前趋 pred:=pred(r[t],key);//右子树的返回值 if pred=key then //如果右子树的返回值=key说明在右子树中没找到key的前趋 pred:=v[t]; //右子树没有key的前趋,那你就是了。 end; end; function succ(var t,key:longint):longint;inline;//找key的后继 begin if t=0 then exit(key); if v[t]<=key then succ:=succ(r[t],key) else begin succ:=succ(l[t],key); if succ=key then succ:=v[t]; end; end; procedure order;inline;//操作解释和执行 var a,b:longint; begin readln(a,b); case a of 1:insert(root,b); 2:delete(root,b); 3:writeln(find(root,b)); 4:writeln(rank(root,b)); 5:writeln(select(root,b)); 6:writeln(pred(root,b)); 7:writeln(succ(root,b)); end; end; procedure main;inline;//主模块 var i:longint; begin init; for i:=1 to n do order; end; begin//主程序 main; end.
{输入共一行表示m进制的n化成十进制的数。} var s:string;sum,n,m,i,r,t,c:longint; begin readln(s); val(copy(s,pos(' ',s)+1,length(s)),m,c); delete(s,pos(' ',s),length(s)); {使整数m中放进制,字符串s中放需要的数} t:=1;n:=length(s);sum:=0; for i:=n downto 1 do begin case s[i] of '0'..'9':r:=ord(s[i])-48; 'A'..'Z':r:=ord(s[i])-55; end; sum:=sum+r*t; t:=t*m; end; write(sum); end.
{输入共一行表示n的m进制。} var a:char; i,n,m:integer; c:array[10..16]of char; //存储10~16对应的7个字母 procedure nm(n:integer); //M为全局变量,所以这里只要N就可以了 var r:integer; begin if n=0 then exit; //直到商等于0 r:=n mod m; //求余数 nm(n div m); //反向取余数 if r>=10 then write(c[r]) else write(r); //大于10的数特殊处理 end; begin a:='A'; for i:=10 to 16 do begin c[i]:=a; a:=succ('A') end; //后继函数,即前一个或后一个ASCII码代表的字符. 如:pred('b')='a',succ('b')='c'. readln(n,m); //输入 nm(n); //引用过程,过程中包含输出。 end。
f[U1]=初始值; for k←2 to n do //枚举每一个阶段 for U取遍所有状态 do for X取遍所有决策 do f[Uk]=opt{f[Uk-1]+L[Uk-1,Xk-1]}; L[Uk-1,Xk-1]: 状态Uk-1通过策略Xk-1到达状态Uk 的费用 输出:f[Un]:目标
f[Un]=初始值; for k←n-1 downto 1 do //枚举阶段 for U取遍所有状态 do //枚举状态 for X取遍所有决策 do //枚举决策 f[Uk]=opt{f[Uk+1]+L[Uk,Xk]}; L[Uk,Xk]:状态Uk通过策略Xk到达状态Uk+1的费用 输出:f[U1]:目标
function fac(n1:longint):longint; var j,k:longint; begin k:=1; for j:=1 to n do k:=k*j; fac:=k; end;
{a^b mod n} function f(a,b,n:int64):int64; var t,y:int64; begin t:=1; y:=a; while b<>0 do begin if(b and 1)=1 then t:=t*y mod n; y:=y*y mod n; {这里用了一个很强大的技巧,y*y即求出了a^(2^(i-1))不知道这是什么的看原理} b:=b shr 1;{去掉已经处理过的一位} end; exit(t); end;
h[0]:=1; h[1]:=1; for i:=2 to n do begin j:=i-1; k:=0; while k<>i do begin h[i]:=h[i]+h[k]*h[j]; dec(j); inc(k); end; end;
{二叉树的先序遍历} type note=record father,lch,rch:longint;end; var a:array[1..100] of note;n,j,t,m:longint;s:longint; procedure duru; var i:longint;f,l,r:longint; begin read(n); for i:=1 to n do begin readln(f,l,r); a[f].lch:=l;{f的左孩子为l} a[f].rch:=r;{f的右孩子为r} if l<>0 then a[l].father:=f;{如果有左孩子那么左孩子的父亲是f} if r<>0 then a[r].father:=f;{如果有右孩子那么右孩子的父亲是f} end; end;{输入的过程,第一个是父亲,后两个为左右孩子,0表示空} function root:longint; var i:longint; begin for i:=1 to n do{i表示结点} if a[i].father=0 then begin root:=i;exit;{如果这个结点的父亲为零,则这个结点就是根} end; end;{找根的程序} procedure xiangen(t:longint); begin if t<>0 then begin write(t,' ');{先根} xiangen(a[t].lch);{再对左子树先根遍历,左孩子当根} xiangen(a[t].rch);{再对右子树先根遍历,后孩子当根} end; end;{进行先序遍历并输出的程序} begin duru;m:=root; writeln(m);xiangen(m); end. {二叉树的中序遍历} procedure zhonggen(t:longint); begin if t<>0 then begin write(t,' '); zhonggen(a[t].lch); zhonggen(a[t].rch); end; end; {二叉树的后序遍历} procedure hougen(t:longint); begin if t<>0 then begin hougen(a[t].lch); hougen(a[t].rch); write(t,' ') end; end; {已知二叉树的前序遍历与中序遍历求后序遍历} var s1,s2:string; procedure work(s1,s2:string); var b,a:longint;{b,a的值在不断改变,必须放在局部变量里} begin if s1<>'' then begin b:=length(s1); a:=pos(s1[1],s2); work(copy(s1,2,a-1),copy(s2,1,a-1)); work(copy(s1,a+1,b-a),copy(s2,a+1,b-a)); write(s1[1]); end; end; begin readln(s1);readln(s2); work(s1,s2); end.
//二叉树的先序遍历 type note=record father,lch,rch:longint;end; var a:array[1..100] of note;n,j,t,m:longint;s:longint; procedure duru; var i:longint;f,l,r:longint; begin read(n); for i:=1 to n do begin readln(f,l,r); a[f].lch:=l;{f的左孩子为l} a[f].rch:=r;{f的右孩子为r} if l<>0 then a[l].father:=f;{如果有左孩子那么左孩子的父亲是f} if r<>0 then a[r].father:=f;{如果有右孩子那么右孩子的父亲是f} end; end;{输入的过程,第一个是父亲,后两个为左右孩子,0表示空} function root:longint; var i:longint; begin for i:=1 to n do{i表示结点} if a[i].father=0 then begin root:=i;exit;{如果这个结点的父亲为零,则这个结点就是根} end; end;{找根的程序} procedure xiangen(t:longint); begin if t<>0 then begin write(t,' ');{先根} xiangen(a[t].lch);{再对左子树先根遍历,左孩子当根} xiangen(a[t].rch);{再对右子树先根遍历,后孩子当根} end; end;{进行先序遍历并输出的程序} begin duru;m:=root; writeln(m);xiangen(m); end. //二叉树的中序遍历 procedure zhonggen(t:longint); begin if t<>0 then begin write(t,' '); zhonggen(a[t].lch); zhonggen(a[t].rch); end; end; //二叉树的后序遍历 procedure hougen(t:longint); begin if t<>0 then begin hougen(a[t].lch); hougen(a[t].rch); write(t,' ') end; end; //已知二叉树的前序遍历与中序遍历求后序遍历 var s1,s2:string; procedure work(s1,s2:string); var b,a:longint;{b,a的值在不断改变,必须放在局部变量里} begin if s1<>'' then begin b:=length(s1); a:=pos(s1[1],s2); work(copy(s1,2,a-1),copy(s2,1,a-1)); work(copy(s1,a+1,b-a),copy(s2,a+1,b-a)); write(s1[1]); end; end; begin readln(s1);readln(s2); work(s1,s2); end.
初始化;把初始布局存入 设首指针head=0; 尾指针tail:=1; Repeat Inc(head),取出队列首记录为当前被扩展结点; For i:=1 to 规则数 do {r是规则编号} Begin If 新空格位置合法 then Begin If 新布局与队列中原有记录不重复 tail增1,并把新布局存入队尾; if 达到目标 then 输出并退出; End; End; Until head>=tail; {队列空}
初始化;把初始布局存入 设首指针head=0; 尾指针tail:=1; repeat inc(head),取出队列首记录为当前被扩展结点; for i:=1 to 规则数 do {r是规则编号} begin if 新空格位置合法 then begin if 新布局与队列中原有记录不重复 tail增1,并把新布局存入队尾; if 达到目标 then 输出并退出; end; end; until head>=tail; {队列空}
//GCD function gcd(a,b:longint):longint; begin if b=0 then gcd:=a else gcd:=gcd (b,a mod b); end ; //LCM function lcm(a,b:longint):longint; begin if a<b then swap(a,b); lcm:=a; while lcm mod b>0 do inc(lcm,a); end;
//单个判断 function prime (n: longint): boolean; var i longint; begin for i:=2 to trunc(sqrt(n)) do if n mod i=0 then exit(false) exit(true); end; //筛法打表 procedure main; var i,j:longint; begin fillchar(f,sizeof(f),true); f[0]:=false;f[1]:=false; for i:=2 to trunc(sqrt(maxn)) do if f[i] then begin j:=2*i; while j<= maxn do begin f[j]:=false; inc(j,i); end; end; end;
浙公网安备 33010602011771号