大神分析:第三题
这题很水,一开始就想到了矩阵乘法。我们是三项系数为
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
Input
Output
输出满足条件的序列的最大长度。
Sample Input
Sample Output
Data Constraint
Hint
分析:我们需要先进行离散,把左边界排序,因为左边界是有序的,我们做一次最长下降子序列即可。顺便说说,最长下降子序列可以进行优化,如果遇到一个比最后一个数小的,就放入栈中,如果比它大,就插入进栈中,因为他是有序的,二分一下就可缩为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.
Input
Output
输出被偷走的管道的行号和列号以及管道的类型。
Sample Input
..........
暴力。注意一些点即可。
给一组数据
输入: 输出:
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.