vijos-p1011 2008.11.7

vijos-p1011 2008.11.7

背景 Background 

顺治帝福临,是清朝入关后的第一位皇帝。他是皇太极的第九子,生于崇德三年(1638)崇德八年八月二ten+six日在沈阳即位,改元顺治,在位18年。卒于顺治十八年(1661),终24岁。

顺治即位后,由叔父多尔衮辅政。顺治七年,多尔衮出塞射猎,死于塞外。14岁的福临提前亲政。顺治帝天资聪颖,读书勤奋,他吸收先进的汉文化,审时度势,对成法祖制有所更张,且不顾满洲亲贵大臣的反对,倚重汉官。为了使新兴的统治基业长治久安,他以明之兴亡为借鉴,警惕宦官朋党为祸,重视整饬吏治,注意与民休息,取之有节。但他少年气盛,刚愎自用,急噪易怒,当他宠爱的董妃去世后,转而消极厌世,终于匆匆走完短暂的人生历程,英年早逝。他是清朝历史上唯一公开归依禅门的皇帝。

 描述Description  

顺治喜欢滑雪,这并不奇怪,因为滑雪的确很刺激。可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待太监们来载你。顺治想知道载一个区域中最长的滑坡。

区域由一个二维数组给出。数组的每个数字代表点的高度。下面是一个例子

1 2  3  4 5

16 17 18 19 6

15 24 25 20 7

14 23 22 21 8

13 12 11 10 9

顺治可以从某个点滑向上下左右相邻四个点之一,当且仅当高度减小。在上面的例子中,一条可滑行的滑坡为24-17-16-1。当然25-24-23-...-3-2-1更长。事实上,这是最长的一条。

输入格式 Input Format 

输入的第一行表示区域的行数R和列数C(1 <= R,C <= 500)。下面是R行,每行有C个整数,代表高度h,0<=h<=10000。

输出格式 Output Format 

输出最长区域的长度。

样例输入 Sample Input  

5 5

1 2 3 4 5

16 17 18 19 6

15 24 25 20 7

14 23 22 21 8

13 12 11 10 9

样例输出 Sample Output  

25

最长xx序列
program 1--搜索过5组

 program p_1011;
  const fin='in.in';fout='out.out';
  var a:array[1..500,1..500]of longint;
      f:array[1..500,1..500]of boolean;
      f1,f2:text;
      c,r,i,j,max:longint;
  procedure deal(x,y,t:longint);
  begin
     if t>max then max:=t;
     if (x-1>0)and(f[x-1,y])and(a[x-1,y]<a[x,y]) then
                              begin f[x-1,y]:=false;deal(x-1,y,t+1);
                                    f[x-1,y]:=true;end;
     if (x+1<=c)and(f[x+1,y])and(a[x+1,y]<a[x,y])then
                              begin f[x+1,y]:=false;deal(x+1,y,t+1);
                                    f[x+1,y]:=true;end;
     if (y-1>0)and(f[x,y-1])and(a[x,y-1]<a[x,y]) then
                             begin f[x,y-1]:=false;deal(x,y-1,t+1);
                                   f[x,y-1]:=true;end;
     if (y+1<=r)and(f[x,y+1])and(a[x,y+1]<a[x,y]) then
                            begin f[x,y+1]:=false;deal(x,y+1,t+1);
                                  f[x,y+1]:=true;end;
  end;
  begin
   { assign(f1,fin);reset(f1);
    assign(f2,fout);rewrite(f2);}
    read(c,r);
    for i:=1 to c do
      for j:=1 to r do read(a[i,j]);
    fillchar(f,sizeof(f),true);
    max:=0;
    for i:=1 to c do
       for j:=1 to r do
         begin
            fillchar(f,sizeof(f),true);
            f[i,j]:=false;
            deal(i,j,1);
         end;
       writeln(max);
 end.

Program 2--dp+堆,仍然过3

program p_1011;
var c1,r,i,j,max,tt,lc:longint;
    a,b,f,c:array[1..25000]of longint;
procedure sift(l,m:longint);
 var i,j, t:longint;
 begin
 i:=l;j:=2*i;t:=b[i];
 while j<=m do
  begin
   if (j<m) and (a[b[j]]>a[b[j+1]]) then inc(j);
   if a[t]>a[b[j]] then
      begin b[i]:=b[j];i:=j;j:=2*i; end
             else exit;
  b[i]:=t;
 end;
 end;
 procedure init;
 var i:longint;
 begin read(c1,r);tt:=c1*r;
      for i:=1 to tt do
      begin
        read(a[i]);b[i]:=i;
      end;
      for i:=(tt div 2) downto 1 do
     sift(i,tt);lc:=0;
     for i:=tt downto 2 do
     begin
       inc(lc);c[lc]:=b[1];
       b[1]:=b[i];
        sift(1,i-1);
     end;
     inc(lc);c[lc]:=b[1];
     max:=0;
end;
procedure dp;
var i,i1:longint;
begin
    fillchar(f,sizeof(f),0);
    for i:=1 to tt do
      begin i1:=c[i];
          if (i1-r>0)and(a[i1]>a[i1-r])and(f[i1-r]>f[i1]) then f[i1]:=f[i1-r];
          if (i1+r<tt)and(a[i1]>a[i1+r])and(f[i1+r]>f[i1]) then f[i1]:=f[i1+r];
          if (i1 mod r<>1)and(a[i1]>a[i1-1])and(f[i1-1]>f[i1]) then f[i1]:=f[i1-1];
          if (i1 mod r<>0)and(a[i1]>a[i1+1])and(f[i1+1]>f[i1]) then f[i1]:=f[i1+1];
          inc(f[i1]);if f[i1]>max then max:=f[i1];
      end;
    end;
begin
  init;
  dp;
  writeln(max);
end.
Program 3: p+qsort 3 组,但时间很短,只是有个错误号错误号 -1073741571--- 栈溢出

program p_1011;
var c,r,i,j,max,tt:longint;
    a,b,f:array[1..25000]of longint;
procedure qsort(i1,j1:longint);
var
l1,r1,x1,y1:longint;
begin
l1:=i1;r1:=j1;
x1:=a[b[(l1+r1) div 2]];
repeat
while a[b[l1]]<x1 do inc(l1);
while a[b[r1]]>x1 do dec(r1);
 if l1<=r1 then
   begin
   y1:=b[l1];
   b[l1]:=b[r1];
   b[r1]:=y1;
   inc(l1);
   dec(r1);
   end;
until l1>r1;
if r1>i1 then qsort(i1,r1);
if l1<j1 then qsort(l1,j1);
end;
procedure init;
var i:longint;
begin read(c,r);tt:=c*r;
      for i:=1 to tt do
      begin
        read(a[i]);b[i]:=i;
      end;
      qsort(1,tt);
      max:=0;
end;
procedure dp;
var i,i1:longint;
begin
    fillchar(f,sizeof(f),0);
    for i:=1 to tt do
      begin i1:=b[i];
          if (i1-r>0)and(a[i1]>a[i1-r])and(f[i1-r]>f[i1]) then f[i1]:=f[i1-r];
          if (i1+r<tt)and(a[i1]>a[i1+r])and(f[i1+r]>f[i1]) then f[i1]:=f[i1+r];
          if (i1 mod r<>1)and(a[i1]>a[i1-1])and(f[i1-1]>f[i1]) then f[i1]:=f[i1-1];
          if (i1 mod r<>0)and(a[i1]>a[i1+1])and(f[i1+1]>f[i1]) then f[i1]:=f[i1+1];
          inc(f[i1]);if f[i1]>max then max:=f[i1];
      end;
    end;
begin
  init;
  dp;
  writeln(max);
end.


Program 3:很强悍的数据结构处理

{qsort+dp}

program asdf;
type rec=record
      x,y,dat:longint;
     end;
var
  r,c,i,j,ans:longint;
  inf:array[0..250000]of rec;
  nea:array[1..250000,1..4]of longint;
  f:array[0..250000]of longint;
  a:array[0..501,0..501]of longint;
procedure sort(l,r:longint);
  var
    i,j,m:longint;
  begin
   i:=l;j:=r;
   m:=inf[(l+r)div 2].dat;
   while i<j do
    begin
     while inf[i].dat>m do i:=i+1;
     while inf[j].dat<m do j:=j-1;
     if i<=j then
    begin
      a[inf[i].x,inf[i].y]:=j;a[inf[j].x,inf[j].y]:=i;
      inf[0]:=inf[i];inf[i]:=inf[j];inf[j]:=inf[0];
      i:=i+1;j:=j-1;
    end;
    end;
   if l<j then sort(l,j);
   if i<r then sort(i,r);
  end;
begin
  readln(r,c);
  for i:=1 to r do
   begin
     for j:=1 to c do read(a[i,j]);
     readln;
   end;
  for i:=1 to r do
   for j:=1 to c do
     begin
    inf[(i-1)*c+j].dat:=a[i,j];
    inf[(i-1)*c+j].x:=i;
    inf[(i-1)*c+j].y:=j;
    a[i,j]:=(i-1)*c+j;//把矩阵转换成线性表,并在矩阵忠存下在线性表中的标号
     end;
  sort(1,r*c);
  for i:=1 to r*c do
    begin
     nea[i,1]:=a[inf[i].x,inf[i].y-1];
     nea[i,2]:=a[inf[i].x-1,inf[i].y];
     nea[i,3]:=a[inf[i].x,inf[i].y+1];
     nea[i,4]:=a[inf[i].x+1,inf[i].y];
    end;//每个点四个方向相邻的格子在线性表中的标号
  for i:=1 to r*c do f[i]:=1;//初始化
  ans:=1;
  for i:=2 to r*c do
  begin
    for j:=1 to 4 do//最长xx序列
     if (f[nea[i,j]]+1>f[i])and(inf[nea[i,j]].dat>inf[i].dat) then
    begin
     f[i]:=f[nea[i,j]]+1;
    end;
    if f[i]>ans then ans:=f[i];
  end;
  writeln(ans);
end.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值