zoukankan      html  css  js  c++  java
  • 解题报告 跳跃

    跳跃

     

     

     

     

     

    事情出奇的顺利自从高考研讨会过后,z 同学专心准备 noip2010 可能是被 z 同学的 潇洒帅气、阳关所吸引zn 主动约到了 z 同学就这样,zn  z 同学走到了一起~!那是 一次放假,众所周知,hz 的放假,对于不回家的同学就是能走出封闭的 hz 大门好好玩上个小时。Zn 刚与 z 同学吃完 kfc,他们来到了衡水唯一还算比较浪漫的地方(貌似叫什么人 民公园吧,ms ~~

     

     

     

    公园中有许多木桩,每个木桩都有一个高度,活泼的小 z 同学喜欢从一个木桩跳到另 一个木桩上,zn 说太危险了,于是 z 同学让 zn 算出每一次跳跃的危险系数。小 z 每一次跳 跃的范围是一个 k*k 的矩形危险系数为这个矩形内最高的木桩高度减去最小的身为 oier, 你能比学数奥的 zn 算的快吗

     

     

     

     

    第一行三个整数 n(木桩为 n*n 的矩阵kb(小 zz 准备跳跃的次数) 接下来为 n*n 的矩阵,描述木桩的高度

     

    接下来 b 行;每行两个整数 x,y(表示 z 同学跳跃的范围的左上角为第 x 行第 y , 保证跳跃范围不超过矩阵的范围

     

     

     

    B 行,每行对应一次跳跃的危险系数样例输入

    5 3 1

    5 1 2 6 3<<------------------第一行

    1 3 5 2 7

    7 2 4 6 1

    9 9 8 6 5

    0 6 9 3 9

    1 2

     

     

     

     

    5

     

     

     

     

    对于30%的数据

    0<k<=n<=2500<b<=100

    对于100%的数据

    0<k<-n<=2500<b<=1000 000

     

     

    二维的 RMQ ,解法有好多种:

    带标号快排,然后从两端开始找,找到编号满足条件的跳出。(这个东西均摊复杂度很低,但极端情况复杂度巨高,适合对付随机数据,相当好打) 90 

     

    代码 (SueMiller

    program ACRush;

     

    var a:array[0..90000,1..3]of longint;

        i,j,x,y,l,r:longint;

        n,k,b,temp:longint;

     

    procedure quicksort(l,r:longint);

    var x,i,j:longint;

    begin

     i:=l; j:=r; x:=a[(l+r)>>1,1];

     repeat

      while a[i,1]<x do inc(i);

      while x<a[j,1] do dec(j);

      if i<=j then

       begin

       a[0]:=a[i]; a[i]:=a[j]; a[j]:=a[0];

       inc(i); dec(j);

       end;

     until i>j;

     if l<j then quicksort(l,j);

     if i<r then quicksort(i,r);

    end;

     

    begin

      assign(input,'jump.in');reset(input);

      assign(output,'jump.out');rewrite(output);

     

      readln(n,k,b);

      fillchar(a,sizeof(a),0);

      temp:=0;

      for i:=1 to n do

        begin

          for j:=1 to n do

            begin

              read(x);

              inc(temp);

              a[temp,1]:=x;

              a[temp,2]:=i;

              a[temp,3]:=j;

            end;

          readln;

        end;

     

      quicksort(1,temp);

     

      for i:=1 to b do

        begin

          readln(x,y);

          for l:=1 to temp do

            if ((a[l,2]>=x) and (a[l,2]<=x+k-1))

               and ((a[l,3]>=y) and (a[l,3]<=y+k-1))

            then break;

     

          for r:=temp downto 1 do

            if ((a[r,2]>=x) and (a[r,2]<=x+k-1))

               and((a[r,3]>=y) and (a[r,3]<=y+k-1))

            then break;

     

          writeln(a[r,1]-a[l,1]);

        end;

     

      close(input);close(output);

    End.

     

     

    观察它的数据,会发现询问很多,矩阵很小,所以,可以先把矩阵拆成一行一行的,然后求出每一行中,每一段的最值,用单调队列或 ST ,然后,当读入数据时,将需要求得矩阵的每一行的最值加以比较,比较难打。 100 

     

    代码(LYF

    var

      a,max,min,l,r:array[0..255,0..255] of longint;

      q:array[0..255] of longint;

      x,y,head,tail,i,j,k,n,m,qq:longint;

     

    begin

      assign(input,'jump.in'); reset(input);

      assign(output,'jump.out'); rewrite(output);

      readln(n,m,qq);

      for i:=1 to n do

        for j:=1 to n do

          read(a[i,j]);

      for i:=1 to n do

        begin

          head:=1; tail:=1; q[1]:=1;

          for j:=1 to m-1 do

            begin

              while (head<=tail)and(a[i,q[tail]]>=a[i,j]) do dec(tail);

              inc(tail);

              q[tail]:=j;

            end;

          for j:=m to n do

            begin

              while (head<=tail)and(q[head]+m-1<j) do inc(head);

              while (head<=tail)and(a[i,q[tail]]>=a[i,j]) do dec(tail);

              inc(tail);

              q[tail]:=j;

              l[i,j]:=a[i,q[head]];

            end;

        end;

      for i:=1 to n do

        begin

          head:=1; tail:=1; q[1]:=1;

          for j:=1 to m-1 do

            begin

              while (head<=tail)and(a[i,q[tail]]<=a[i,j]) do dec(tail);

              inc(tail);

              q[tail]:=j;

            end;

          for j:=m to n do

            begin

              while (head<=tail)and(q[head]+m-1<j) do inc(head);

              while (head<=tail)and(a[i,q[tail]]<=a[i,j]) do dec(tail);

              inc(tail);

              q[tail]:=j;

              r[i,j]:=a[i,q[head]];

            end;

        end;

      for j:=m to n do

        begin

          head:=1; tail:=1; q[1]:=1;

          for i:=1 to m-1 do

            begin

              while (head<=tail)and(l[q[tail],j]>=l[i,j]) do dec(tail);

              inc(tail);

              q[tail]:=i;

            end;

          for i:=m to n do

            begin

              while (head<=tail)and(q[head]+m-1<i) do inc(head);

              while (head<=tail)and(l[q[tail],j]>=l[i,j]) do dec(tail);

              inc(tail);

              q[tail]:=i;

              min[i,j]:=l[q[head],j];

            end;

        end;

      for j:=m to n do

        begin

          head:=1; tail:=1; q[1]:=1;

          for i:=1 to m-1 do

            begin

              while (head<=tail)and(r[q[tail],j]<=r[i,j]) do dec(tail);

              inc(tail);

              q[tail]:=i;

            end;

          for i:=m to n do

            begin

              while (head<=tail)and(q[head]+m-1<i) do inc(head);

              while (head<=tail)and(r[q[tail],j]<=r[i,j]) do dec(tail);

              inc(tail);

              q[tail]:=i;

              max[i,j]:=r[q[head],j];

            end;

        end;

      for i:=1 to qq do

        begin

          readln(x,y);

          x:=x+m-1;

          y:=y+m-1;

          writeln(max[x,y]-min[x,y]);

        end;

      close(input); close(output);

    end.

     

    二维 ST ,首先,将一个大矩阵分成 2^k*2^k 的小矩阵,求出小矩阵中的最值,然后每读入一个矩阵后将它分解成小矩阵,直接比较求最值,还算好打,但不好想。 100 

     

    代码(ZSZ

    program foreverzsz;

    var f,g:array[0..250,0..250,0..15] of longint;

        n,b,k,i,j,ii,jj,w,i1,j1,minn,maxx,kk:longint;

        d:array[0..15] of longint;

    function min(a,b:longint):longint;

    begin

      if a<b then exit(a) else exit(b);

    end;

    function max(a,b:longint):longint;

    begin

      if a>b then exit(a) else exit(b);

    end;

    begin

      assign(input,'jump.in');reset(input);

      assign(output,'jump.out');rewrite(output);

      readln(n,b,kk);

      fillchar(f,sizeof(f),120);

      fillchar(g,sizeof(g),0);

      for i:= 1 to n do

        for j:= 1 to n do

          begin

            read(f[i][j][0]);

            g[i][j][0]:=f[i][j][0];

          end;

      d[0]:=1;

      for k:= 1 to 12 do

        d[k]:=d[k-1]<<1;

      w:=trunc(ln(b)/ln(2));

      for k:= 1 to w do

        for i:= 1 to n do

          for j:= 1 to n do

            if (i+d[k]-1<=n)and(j+d[k]-1<=n) then

              begin

                f[i][j][k]:=min(f[i][j][k-1],f[i+d[k-1]][j][k-1]);

                f[i][j][k]:=min(f[i][j][k],f[i][j+d[k-1]][k-1]);

                f[i][j][k]:=min(f[i][j][k],f[i+d[k-1]][j+d[k-1]][k-1]);

                g[i][j][k]:=max(g[i][j][k-1],g[i+d[k-1]][j][k-1]);

                g[i][j][k]:=max(g[i][j][k],g[i][j+d[k-1]][k-1]);

                g[i][j][k]:=max(g[i][j][k],g[i+d[k-1]][j+d[k-1]][k-1]);

              end;

      for i:= 1 to kk do

        begin

          readln(ii,jj);

          i1:=ii+b-1;

          j1:=jj+b-1;

          if f[ii][jj][w]<f[i1-d[w]+1][j1-d[w]+1][w] then minn:=f[ii][jj][w] else minn:=f[i1-d[w]+1][j1-d[w]+1][w];

          if f[ii][j1-d[w]+1][w]<minn then minn:=f[ii][j1-d[w]+1][w];

          if f[i1-d[w]+1][jj][w]<minn then minn:=f[i1-d[w]+1][jj][w];

          if g[ii][jj][w]>g[i1-d[w]+1][j1-d[w]+1][w] then maxx:=g[ii][jj][w] else maxx:=g[i1-d[w]+1][j1-d[w]+1][w];

          if g[ii][j1-d[w]+1][w]>maxx then maxx:=g[ii][j1-d[w]+1][w];

          if g[i1-d[w]+1][jj][w]>maxx then maxx:=g[i1-d[w]+1][jj][w];

          writeln(maxx-minn);

        end;

      close(input);

      close(output);

    end.

     

    这三个方法都可以用在更高维的地方,当然,第二个要是用在高维(四维以上),前提条件是你得有着十分强悍的高维空间想象力。

  • 相关阅读:
    聊聊面试-NoClassDefFoundError 和 ClassNotFoundException 区别
    聊聊面试-int和Integer的区别
    数据库char varchar nchar nvarchar,编码Unicode,UTF8,GBK等,Sql语句中文前为什么加N(一次线上数据存储乱码排查)
    SQL Server数据库阻塞,死锁查询
    数据误操作,教你使用ApexSQLLog工具从 SQLServer日志恢复数据!
    IDEA将Maven项目中指定文件夹下的xml等文件编译进classes
    Tomcat 中文乱码,设置UTF-8
    C#实现前向最大匹、字典树(分词、检索)
    23种设计模式汇总
    Head First设计模式——原型模式和访问者模式
  • 原文地址:https://www.cnblogs.com/SueMiller/p/2220432.html
Copyright © 2011-2022 走看看