本文引用自「kcfzyhq」的部落格
首先我們來看看下面這個圖,這個圖基本表現了題目的意思:乙個卒要從圖的左上角a點走到右下角b點,而其中有一點c為馬的位置,c與其周邊馬能走到的p1~p8點共9個點是不能走的,問有多少種從a走到b的方法
我們可以先把這個問題當數學問題來考慮相信許多朋友以前都遇到過類似的數學問題,對於點[i,j],它的走法數等於它上方點與其左方點走法數之和(因為只能向下或向右走),也就是b[i,j]=b[i-1][j]+b[i][j-1],如下圖就是乙個例子
但換到有馬阻攔的問題中,單純地這樣搜尋就行不通了,如下圖
這張圖所得的答案雖然是正確的,但實際上這樣的操作是錯誤的,圖中藍色的「1」應該改為0,如下圖
因為這個位置後面被馬頭擋住,自然是行不通的,值應為0,在這個例子中這裡的值是1還是0對答案沒有影響,但大家可以想象,如果在最左邊一條邊上,乙個點上下都是馬能走到的位置,值還為1的話,就會影響它右側點的值(不懂的看下面這個例子)
就像上圖,正常情況下紅色點所在的一整列初始賦值都是1,但是紅色點實際值應該為0,如果值仍賦為1,則會導致藍色點的值比實際值大1,從而導致整個結果錯誤。
因此,我們在賦初值時,要專門考慮最上和最左一列的情況,具體方法參見**
哦,對了,這道題的資料可能很大,注意要開long long,否則會炸
#include
#include
using
namespace
std;
long
long b[21][21];
int n,m,a,b;
void init()
}if(a-2>=0&&b-1>=0) //把馬的位置和所有馬能走到的位置都賦為0,注意考慮邊界
b[a-2][b-1]=0;
if(a-2>=0&&b+1
<=m)
b[a-2][b+1]=0;
if(a-1>=0&&b-2>=0)
b[a-1][b-2]=0;
if(a-1>=0&&b+2
<=m)
b[a-1][b+2]=0;
if(a+1
<=m&&b-2>=0)
b[a+1][b-2]=0;
if(a+2
<=n&&b-1>=0)
b[a+2][b-1]=0;
if(a+1
<=n&&b+2
<=m)
b[a+1][b+2]=0;
if(a+1
<=n&&b+1
<=m)
b[a+2][b+1]=0;
b[a][b]=0;
}int main()
/*這裡就是處理所說的特殊情況,相當於如果在最上一行或者最左一行
出現乙個馬,那麼後面的值都賦為0
*/else
if (i==0)else
if (j==0)else}}
}printf("%lld\n",b[n][m]);
}
noip2002 普及組 過河卒
題目描述 棋盤上a點有乙個過河卒,需要走到目標b點。卒行走的規則 可以向下 或者向右。同時在棋盤上c點有乙個對方的馬,該馬所在的點和所有跳躍一步可達的點稱為對方馬的控制點。因此稱之為 馬攔過河卒 棋盤用座標表示,a點 0,0 b點 n,m n,m為不超過20的整數 同樣馬的位置座標是需要給出的。現在...
P1002 NOIP2002 普及組 過河卒
最近在洛谷刷題,決定用部落格把自己的解題思路以及踩過的坑整理總結一下 先來看看題目吧 棋盤上 aa 點有乙個過河卒,需要走到目標 bb 點。卒行走的規則 可以向下 或者向右。同時在棋盤上 cc 點有乙個對方的馬,該馬所在的點和所有跳躍一步可達的點稱為對方馬的控制點。因此稱之為 馬攔過河卒 棋盤用座標...
P1002 NOIP2002 普及組 過河卒
棋盤上 aa 點有乙個過河卒,需要走到目標 bb 點。卒行走的規則 可以向下 或者向右。同時在棋盤上 cc 點有乙個對方的馬,該馬所在的點和所有跳躍一步可達的點稱為對方馬的控制點。因此稱之為 馬攔過河卒 棋盤用座標表示,aa 點 0,0 0,0 bb 點 n,m n,m 同樣馬的位置座標是需要給出的...