总结

 

 

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:=1repeat    
        inc(head),取出队列首记录为当前被扩展结点;   
        for  i:=1  to   规则数 do    {r是规则编号}
        begin
            if  新空格位置合法  then
            begin
                if  新布局与队列中原有记录不重复
                     tail增1,并把新布局存入队尾;
              if  达到目标  then  输出并退出;
            endenduntil  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;

 

posted on 2015-10-29 17:52  川汉唐  阅读(152)  评论(0)    收藏  举报

导航