南沙C信++奧賽陳老師解一本通題: 1314:【例3.6】過河卒(Noip2002)

南沙区信奥赛陈老师發表於2024-09-10

【題目描述】

棋盤上A點有一個過河卒,需要走到目標B點。卒行走的規則:可以向下、或者向右。同時在棋盤上的某一點有一個對方的馬(如C點),該馬所在的點和所有跳躍一步可達的點稱為對方馬的控制點,如圖3-1中的C點和P1,……,P8,卒不能透過對方馬的控制點。棋盤用座標表示,A點(0,0)、B點(n, m) (n,m為不超過20的整數),同樣馬的位置座標是需要給出的,C≠A且C≠B。現在要求你計算出卒從A點能夠到達B點的路徑的條數。

【輸入】

給出n、m和C點的座標。

【輸出】

從A點能夠到達B點的路徑的條數。

【輸入樣例】

8 6 0 4

【輸出樣例】

1617

#include <bits/stdc++.h>
using namespace std;
int h_d[9][2]={{0,0},{-1,-2},{1,-2},{-1,2},{1,2},{2,-1},{-2,-1},{2,1},{-2,1}};
int s_d[2][2]={{0,1},{1,0}};
long long a[100][100];
bool h[100][100];
long long ans=0;
using namespace std;
int n,m,ex,ey;
/*
void dfs(int x,int y)
{
	if(x==n&&y==m)
	{
		ans++;
		return;
	}
	for(int i=0;i<2;i++)
	{
		int nx=x+s_d[i][0]; 
		int ny=y+s_d[i][1]; 
		if(nx>=0&&nx<=n&&ny>=0&&ny<=m && a[nx][ny]==0 ) //可通行 
			dfs(nx,ny);			
	}
}*/
int main()
{
	cin>>n>>m>>ex>>ey;
	memset(a,0,sizeof(a));
	memset(h,false,sizeof(h));
	for(int i=0;i<9;i++)
	{
		int nx = ex + h_d[i][0];
		int ny= ey + h_d[i][1];
		if(nx>=0&&nx<=n&&ny>=0&&ny<=m)
			h[nx][ny]=true;
	}
	//dfs(0,0);
	//實際上a[0][0]點可以有兩種走法但初始化他為1 是因為a[0][1]的走法只有一種且等於a[0][0] 同理 a[1][0]的走法只有一種且 等行a[0][0]
    a[0][0]=1;
	for(int i=0;i<=n;i++)
	{
		for(int j=0;j<=m;j++)
		{	
			if(h[i][j]==true) //馬的控制點 
				continue;
			if(i==0&&j==0)
				continue;
			else if(i-1>=0&&j-1>=0)
				a[i][j]=a[i][j-1]+a[i-1][j]; //當前的走法等 於左邊或從上面走法之和 
			else if(i-1<0)  //邊界只有上,沒有左,即在第一列 
				a[i][j]=a[i][j-1];
			else
				a[i][j]=a[i-1][j]; //邊界只有左,沒有上,即在最後行 
		}
	}		
	//cout<<ans<<endl;
	cout<<a[n][m];
	return 0;
}
南沙C信++奧賽陳老師解一本通題:  1314:【例3.6】過河卒(Noip2002)

相關文章