hrbustojA.棋盤村(2016級新生程序設計全國邀請賽 )

Description

 

   一名騎着馬的強盜闖進了原本平靜祥和的棋盤村,爲了通知村裏的士兵來打敗強盜,你必須要通知位於棋盤村最下方的兵營。棋盤村的地形就像是一張棋盤,你所在的位置爲A點(0,0),兵營位於棋盤村的右下角B點(n,m)。你每次只能走一步,可以選擇向下走,也可以選擇向右走。但是強盜所在的位置和強盜的馬一次所能跳到的位置是不可以走過去的(強盜的馬的移動方法與象棋中的馬相同)。請計算出從A點能夠走到B點的所有路徑條數。


Input

首先輸入一個整數t,代表有t測試數據。

每組測試數據爲四個整數,即B點的座標(nm)和強盜的座標(xy)。

1 < n,m < 20.


Output

輸出一個整數即路徑的條數。

Sample Input

2

6 6 3 2

8 8 3 5
Sample Output

17

1393



這個題開始用dfs深搜發現超時了,然後改用dp,就是把每一次深搜的結果存一下.這個題強盜的馬的位置比較難討論,所以我給它上下左右多開了兩行,這樣的話討論了之後就不用考慮數組越界的問題了.

#include<iostream>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
ll n,m,x,y;
ll pan[1003][1003];
ll re[1003][1003];

ll dp(int p,int q)
{
	if(p<2||q<2||p>n+2||q>m+2||pan[p][q]==1)  return 0;
	if(p==n+2&&q==m+2)  
	{
		return 1;
	}
	if(re[p][q]!=0)
	{
		return re[p][q];
	}
	else  re[p][q]=dp(p+1,q)+dp(p,q+1);
		return re[p][q];
}
int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		cin>>n>>m>>x>>y;
		memset(re,0,sizeof(re));
		memset(pan,0,sizeof(pan));
		x=x+2,y=y+2;
		pan[x][y]=1;  //標記強盜的座標爲1
		pan[x-2][y-1]=1,pan[x-1][y-2]=1;
		pan[x+2][y-1]=1,pan[x+1][y-2]=1;
		pan[x-2][y+1]=1,pan[x-1][y+2]=1;
		pan[x+2][y+1]=1,pan[x+1][y+2]=1;
		cout<<dp(2,2)<<endl;
	}
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章