中山培训(三题)

来源:互联网 发布:网络爬虫怎么找兼职 编辑:程序博客网 时间:2024/04/27 18:43

大神分析:第三题


这题很水,一开始就想到了矩阵乘法。我们是三项系数为

f[i-1],f[i],sum

因为下一项为f[i],f[i+1],sum+f[i],所以得到矩阵

0  1   0

1   1   1

0   0   1

就可以用矩阵乘法进行计算。

程序:

type

 arr=array[1..3,1..3] of longint;

const

 b:arr=((0,1,0),(1,1,1),(0,0,1));

 

var

 a:arr;

 n,i,j,x,y:longint;

procedure jzcf(b:Arr;var a:Arr);

var i,j,k:longint;

   c:Arr;

 begin

 fillchar(c,sizeof(c),0);

  fori:=1 to 3 do

   forj:=1 to 3 do

    fork:=1 to 3 do

    c[i,k]:=(c[i,k]+a[i,j]*b[j,k]) mod 10000;

 a:=c;

 end;

 

procedure power(p:longint);

 begin

  ifp<=1 then exit;

 power(p shr 1);

 jzcf(a,a);

  ifp and 1=1 then jzcf(b,a);

 end;

 

procedure main;

 vari,j,k,s,t:longint;

     c,d:arr;

begin

 fillchar(c,sizeof(c),0);

 ifx=1 then s:=0

 else

  begin

  a:=b;

  power(x-1);

   d[1,1]:=0;d[1,2]:=1; d[1,3]:=0;

   fori:=1 to 1 do

    forj:=1 to 3 do

     fork:=1 to 3 do

     c[i,k]:=(c[i,k]+a[i,j]*b[j,k]) mod 10000;

  s:=c[1,3];

  fillchar(c,sizeof(c),0);

  end;

  a:=b;

  power(y);

   d[1,1]:=0;d[1,2]:=1; d[1,3]:=0;

   fori:=1 to 1 do

    forj:=1 to 3 do

     fork:=1 to 3 do

     c[i,k]:=(c[i,k]+a[i,j]*b[j,k]) mod 10000;

  t:=c[1,3];

  fillchar(c,sizeof(c),0);

 if t-s>=0then writeln(t-s)

        else writeln(t+10000-s);

end;

begin

 read(n);

 fori:=1 to n do

 begin

  read(x,y);

 main;

 end;

end.

 

Description

  Alice收到一些很特别的生日礼物:区间。即使很无聊,Alice还是能想出关于区间的很多游戏,其中一个是,Alice从中选出最长的不同区间的序列,其中满足每个区间必须在礼物中,另序列中每个区间必须包含下一个区间。
  编程计算最长序列的长度。

Input

  输入文件第一行包含一个整数N(1<=N<=100000),表示区间的个数。
  接下来N行,每行两个整数A和B描述一个区间(1<=A<=B<=1000000)。

Output

  输出满足条件的序列的最大长度。

Sample Input

输入1:

3

3 4

2 5

1 6



输入2:

5

10 30

20 40

30 50

10 60

30 40



输入3:

6

1 4

1 5

1 6

1 7

2 5

3 5

Sample Output

输出1:

3



输出2:

3



输出3:

5

Data Constraint

Hint

【样例解释】
  例3中可以找到长度为5的区间序列是:[1,7]、[1,6]、[1,5]、[2,5]、[3,5]

 

分析:我们需要先进行离散,把左边界排序,因为左边界是有序的,我们做一次最长下降子序列即可。顺便说说,最长下降子序列可以进行优化,如果遇到一个比最后一个数小的,就放入栈中,如果比它大,就插入进栈中,因为他是有序的,二分一下就可缩为O(NlogN);

 

var

 x,y:array[0..100000] of longint;

 f:array[0..100000] of longint;

 i,j,n,num,k,l,r,mid,ans:longint;

procedure qsort(l,r:longint);

 vari,j,mid,t,mid1:longint;

begin

 ifl>=r then exit;

 i:=l; j:=r;

 mid:=x[(l+r) shr 1];

 mid1:=y[(l+r) shr 1];

 repeat

  while(x[i]<mid) or (x[i]=mid) and (y[i]>mid1) do inc(i);

  while(x[j]>mid) or (x[j]=mid) and (y[j]<mid1) do dec(j);

  ifi<=j then

   begin

   t:=x[i]; x[i]:=x[j]; x[j]:=t;

   t:=y[i]; y[i]:=y[j]; y[j]:=t;

   inc(i); dec(j);

   end;

 untili>j;

qsort(l,j);

qsort(i,r);

end;

 

begin

 readln(n);

 fori:=1 to n do

 readln(x[i],y[i]);

 qsort(1,n);

 k:=1;f[k]:=y[1];

 fori:=2 to n do

  begin

   ify[i]<=f[k] then

    begin

    inc(k);

    f[k]:=y[i];

    end

   else

   begin

  l:=1; r:=k;

   whilel<=r do

    begin

    mid:=(l+r) shr 1;

     iff[mid]>=y[i] then l:=mid+1 else r:=mid-1;

    end;

   f[l]:=y[i];

   end;

  end;

 writeln(k);

end.

 

  请你帮忙设计一个从城市M到城市Z的输油管道,现在已经把整个区域划分为R行C列,每个单元格可能是空的也可能是以下7种基本管道之一:
  

  油从城市M流向Z,‘+’型管道比较特殊,因为石油必须在两个方向(垂直和水平)上传输,如下图所示:

        
      

  现在恐怖分子弄到了输油管道的设计图,并把其中一个单元格中的管道偷走了,请你帮忙找到偷走的管道的位置以及形状。

Input

  第一行包含两个整数R和C(1<=R,C<=25)。
  接下来R行每行C个字符描述被偷之后的形状,字符分为以下三种:
  (1)‘.’表示空;
  (2)字符‘|’(ASCII为124)、‘-’、‘+’、‘1’、‘2’、‘3’、‘4’描述管道的形状;
  (3)‘M’和‘Z’表示城市,两个都是只出现一次。
  输入保证石油的流向是唯一的,只有一个管道跟M和Z相连,除此此外,保证没有多余的管道,也就是说所有的管道在加进被偷的管道后一定都会被用上。
  输入保证有解而且是唯一的。

Output

  输出被偷走的管道的行号和列号以及管道的类型。

Sample Input

输入1:

3 7

.......

.M-.-Z.

.......



输入2:

3 5

..1-M

1-+..

Z.23.



输入3:

6 10

Z.1----4..

|.|....|..

|..14..M..

2-+++4....

..2323....

..........

 

 

暴力。注意一些点即可。

给一组数据

输入:                   输出:

10 10                             +

..........

..........

.........Z

1---4....|

|1-4|....|

||13|....|

|2.-3....|

2-+------3

..|.......

..M.......

 

var

 a:array [1..50,1..50] of char;

 b:array [1..10,1..2] of longint;

 h:array [1..10] of longint;

 i,j,n,m,sx,sy,ex,ey,num,t:longint;

 f:boolean;

procedure dfs(x,y,z,t:longint);

begin

 ifz=0 then f:=true;

 if(x>n) or (y>m) or (x<1) or (y<1) then exit;

 if(a[x,y]='.') then

 begin

   ifz=1 then

  begin

   inc(num);

   b[num,1]:=x; b[num,2]:=y;

   h[num]:=t;

  end;

  f:=false;

  exit;

 end;

 iff=false then exit;

 iford(a[x,y])=124 then

  ift=1 then dfs(x-1,y,1,1)

        else dfs(x+1,y,1,3);

 ifa[x,y]='-' then

  ift=2 then dfs(x,y+1,1,2)

        else dfs(x,y-1,1,4);

 ifa[x,y]='+' then

 case t of

  1:dfs(x-1,y,1,1);

  2:dfs(x,y+1,1,2);

  3:dfs(x+1,y,1,3);

  4:dfs(x,y-1,1,4);

 end;

 ifa[x,y]='1' then

 case t of

  1:dfs(x,y+1,1,2);

   4:dfs(x+1,y,1,3);

 end;

 ifa[x,y]='2' then

 case t of

  4:dfs(x-1,y,1,1);

  3:dfs(x,y+1,1,2);

 end;

 ifa[x,y]='3' then

 case t of

  3:dfs(x,y-1,1,4);

  2:dfs(x-1,y,1,1);

 end;

 ifa[x,y]='4' then

 case t of

  1:dfs(x,y-1,1,4);

  2:dfs(x+1,y,1,3);

 end;

end;

 

begin

 readln(n,m);

 fori:=1 to n do

 begin

  for j:=1 to m do

   begin

    read(a[i,j]);

    if a[i,j]='Z' then begin sx:=i; sy:=j; end;

    if a[i,j]='M' then begin ex:=i; ey:=j; end;

   end;

  readln;

 end;

 

 dfs(sx,sy+1,0,2);

 dfs(sx,sy-1,0,4);

 dfs(sx+1,sy,0,3);

 dfs(sx-1,sy,0,1);

 dfs(ex,ey+1,0,2);

 dfs(ex,ey-1,0,4);

 dfs(ex+1,ey,0,3);

 dfs(ex-1,ey,0,1);

 dfs(b[1,1],b[1,2]+1,0,2);

 dfs(b[1,1],b[1,2]-1,0,4);

 dfs(b[1,1]+1,b[1,2],0,3);

 dfs(b[1,1]-1,b[1,2],0,1);

 write(b[1,1],' ',b[1,2],' ');

 fori:=1 to 1 do

  forj:=i+1 to 2 do

   ifh[i]>h[j] then

   begin

    t:=h[i];

    h[i]:=h[j];

    h[j]:=t;

   end;

   ifnum>2 then begin write('+'); exit; end;

   if(h[1]=1) and (h[2]=3) then write(chr(124));

   if(h[1]=2) and (h[2]=4) then write('-');

   if(h[1]=1) and (h[2]=4) then write(1);

   if(h[1]=3) and (h[2]=4) then write(2);

   if(h[1]=2) and (h[2]=3) then write(3);

   if(h[1]=1) and (h[2]=2) then write(4);

  end.

 


0 0
原创粉丝点击