(昨天的)codevs天梯过河卒 简短的棋盘dp
2017-02-03 13:18
218 查看
题目:
如图,A 点有一个过河卒,需要走到目标 B 点。卒行走规则:可以向下、或者向右。同时在棋盘上的任一点有一个对方的马(如上图的C点),该马所在的点和所有跳跃一步可达的点称为对方马的控制点。例如上图 C 点上的马可以控制 9 个点(图中的P1,P2 … P8 和 C)。卒不能通过对方马的控制点。
棋盘用坐标表示,A 点(0,0)、B 点(n,m)(n,m 为不超过 20 的整数,并由键盘输入),同样马的位置坐标是需要给出的(约定: C不等于A,同时C不等于B)。现在要求你计算出卒从 A 点能够到达 B 点的路径的条数。
1<=n,m<=15
代码:
const
dx:array [1..8] of longint=(2,1,-1,-2,-2,-1,1,2);
dy:array [1..8] of longint=(1,2,2,1,-1,-2,-2,-1);
maxn=50;
var
f:array [-1..maxn,-1..maxn] of longint;
flag:array [-1..maxn,-1..maxn] of boolean;
n,m,x,y:longint;
procedure init;
var
i,j:longint;
begin
readln(n,m,x,y);
fillchar(flag,sizeof(flag),true);
flag[x,y]:=false;
f[0,0]:=1;
for i:=1 to 8 do
if (x+dx[i]>=0) and (x+dx[i]<=n) and (y+dy[i]>=0) and (y+dy[i]<=m) then
flag[x+dx[i],y+dy[i]]:=false;
for i:=1 to n do
flag[i,-1]:=false;
for i:=1 to m do
flag[-1,i]:=false;
end;
procedure main;
var
i,j:longint;
begin
for i:=0 to n do
for j:=0 to m do
if flag[i,j] and ((i<>0) or (j<>0))then
begin
if flag[i-1,j] and (f[i-1,j]<>0) then
inc(f[i,j],f[i-1,j]);
if flag[i,j-1] and (f[i,j-1]<>0) then
inc(f[i,j],f[i,j-1]);
end;
writeln(f[n,m]);
end;
begin
init;
main;
end.
如图,A 点有一个过河卒,需要走到目标 B 点。卒行走规则:可以向下、或者向右。同时在棋盘上的任一点有一个对方的马(如上图的C点),该马所在的点和所有跳跃一步可达的点称为对方马的控制点。例如上图 C 点上的马可以控制 9 个点(图中的P1,P2 … P8 和 C)。卒不能通过对方马的控制点。
棋盘用坐标表示,A 点(0,0)、B 点(n,m)(n,m 为不超过 20 的整数,并由键盘输入),同样马的位置坐标是需要给出的(约定: C不等于A,同时C不等于B)。现在要求你计算出卒从 A 点能够到达 B 点的路径的条数。
1<=n,m<=15
代码:
const
dx:array [1..8] of longint=(2,1,-1,-2,-2,-1,1,2);
dy:array [1..8] of longint=(1,2,2,1,-1,-2,-2,-1);
maxn=50;
var
f:array [-1..maxn,-1..maxn] of longint;
flag:array [-1..maxn,-1..maxn] of boolean;
n,m,x,y:longint;
procedure init;
var
i,j:longint;
begin
readln(n,m,x,y);
fillchar(flag,sizeof(flag),true);
flag[x,y]:=false;
f[0,0]:=1;
for i:=1 to 8 do
if (x+dx[i]>=0) and (x+dx[i]<=n) and (y+dy[i]>=0) and (y+dy[i]<=m) then
flag[x+dx[i],y+dy[i]]:=false;
for i:=1 to n do
flag[i,-1]:=false;
for i:=1 to m do
flag[-1,i]:=false;
end;
procedure main;
var
i,j:longint;
begin
for i:=0 to n do
for j:=0 to m do
if flag[i,j] and ((i<>0) or (j<>0))then
begin
if flag[i-1,j] and (f[i-1,j]<>0) then
inc(f[i,j],f[i-1,j]);
if flag[i,j-1] and (f[i,j-1]<>0) then
inc(f[i,j],f[i,j-1]);
end;
writeln(f[n,m]);
end;
begin
init;
main;
end.
相关文章推荐
- (昨天的)codevs天梯 传纸条 暴力dp
- (昨天的)codevs 天梯 统计单词个数 dp
- (昨天的)codevs天梯 数的划分 dp
- CODE[VS] 1105 过河 状态压缩DP
- (昨天的)codevs天梯 石子归并
- Code[vs]1010过河卒(dfs不成+棋盘dp)
- codevs1219 骑士遍历(棋盘DP)
- code vs 1711 棋盘分割 (dp)
- 【日常学习】【棋盘DP】【多线程DP】codevs1169 传纸条题解
- codevs1219 骑士遍历(棋盘DP)
- [CodeVs1050]棋盘染色2(状态压缩DP)
- codevs1169 传纸条(棋盘dp)
- 【基础练习】【线性DP+离散化】codevs1105 过河题解
- code(vs)1219 骑士游历 (棋盘dp)
- (昨天的)codevs天梯 逃跑的拉尔夫 dfs
- codevs1169 传纸条(棋盘dp)
- Codevs 1358 棋盘游戏(状压DP)
- code(vs)1010 过河卒 (棋盘dp)
- Code[vs]数字三角形(基础棋盘dp)
- codevs 1169 传纸条 && 1043 方格取数(棋盘DP)