列表

详情


NC16708. [NOIP2002]过河卒

描述

如图,A 点有一个过河卒,需要走到目标 B 点。卒行走规则:可以向下、或者向右。同时在棋盘上的任一点有一个对方的马(如上图的C点),该马所在的点和所有跳跃一步可达的点称为对方马的控制点。例如上图 C 点上的马可以控制 9 个点(图中的P1,P2 … P8 和 C)。卒不能通过对方马的控制点。
棋盘用坐标表示,A 点(0,0)、B 点(n,m)(n,m 为不超过 20 的整数,并由键盘输入),同样马的位置坐标是需要给出的(约定: C<>A,同时C<>B)。现在要求你计算出卒从 A 点能够到达 B 点的路径的条数。

输入描述

输入B点的坐标(n,m)以及对方马的坐标(X,Y){不用判错}

输出描述

输出一个整数(路径的条数)。

示例1

输入:

6 6 3 2

输出:

17

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

Pascal(fpc 3.0.2) 解法, 执行用时: 2ms, 内存消耗: 256K, 提交时间: 2019-08-25 10:18:41

var
 a:array[-2..22,-2..22] of longint;
 d:array[-1..20,-1..20]of int64;
 x,y,b,c,i,j:longint;
begin
 read(x,y,b,c);
 a[b,c]:=1; 
 a[b+2,c+1]:=1;
 a[b-2,c+1]:=1;
 a[b-1,c+2]:=1;
 a[b+1,c+2]:=1;
 a[b+2,c-1]:=1;
 a[b-2,c-1]:=1;
 a[b-1,c-2]:=1;
 a[b+1,c-2]:=1;
 d[0,0]:=1;
 for i:=0 to x do
  for j:=0 to y do
   if(a[i,j]=0)and((i<>0)or(j<>0))then d[i,j]:=d[i-1,j]+d[i,j-1];
 write(d[x,y]);
end.

C 解法, 执行用时: 2ms, 内存消耗: 360K, 提交时间: 2023-07-17 19:56:05

#include<stdio.h>
#include<math.h>

int main()
{
	int i,j,n,m,x,y;
	long long dp[22][22]={0};
	scanf("%d %d %d %d",&n,&m,&x,&y);
	n++;m++;x++;y++;
	dp[0][1]=1;
	for(i=1;i<=n;i++)
	{
		for(j=1;j<=m;j++)
		{
			if(abs(i-x)+abs(j-y)==3&&i!=x&&j!=y||i==x&&j==y);
			//i!=x&&j!=y排除因为abs()函数导致的和马同直线dp[][]也为0 
			else dp[i][j]=dp[i-1][j]+dp[i][j-1];
		}
	}
	printf("%lld\n",dp[n][m]);
}

C++(g++ 7.5.0) 解法, 执行用时: 3ms, 内存消耗: 416K, 提交时间: 2023-07-04 10:53:59

#include<bits/stdc++.h>

using namespace std;

long long dp[30][30];
int n,m,x,y,i,j;

int main()
{
    cin>>n>>m>>x>>y;
    dp[1][1]=1;
    x+=1,y+=1,n+=1,m+=1;
    for(i=1;i<=n;i++){
        for(j=1;j<=m;j++){
            dp[1][1]=1;
            if(abs(i-x)*abs(j-y)==2||i==x&&j==y)    continue;
            dp[i][j]=dp[i-1][j]+dp[i][j-1];
        }
}
    cout<<dp[n][m];
}

C++14(g++5.4) 解法, 执行用时: 3ms, 内存消耗: 504K, 提交时间: 2020-07-22 14:05:05

#include<bits/stdc++.h>

using namespace std;

int n,m,x,y;
long long a[120][120];

int main(){
    cin>>n>>m>>x>>y;
    ++n,++m,++x,++y,a[1][0]=1;
    
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(abs(x-i)+abs(y-j)==3&&x!=i&&y!=j||(x==i&&y==j))continue;
            else a[i][j]=a[i-1][j]+a[i][j-1];
        }
    }
    
    cout<<a[n][m];
}

C++11(clang++ 3.9) 解法, 执行用时: 2ms, 内存消耗: 476K, 提交时间: 2020-08-12 16:16:04

#include<bits/stdc++.h>
using namespace std;
long long f[25][25];
int bn,bm,mx,my;
int main(){
	scanf("%d%d%d%d",&bn,&bm,&mx,&my);
	bn++,bm++,mx++,my++;
	f[0][1]=1;
	for(int i=1;i<=bn;i++)
	for(int j=1;j<=bm;j++)
	if(abs(i-mx)+abs(j-my)==3&&i!=mx&&j!=my||i==mx&&j==my) ;
		else f[i][j]=f[i-1][j]+f[i][j-1];
	cout<<f[bn][bm];
	return 0;
}

上一题