P1002 [NOIP2002 普及组] 过河卒
P1002 [NOIP2002 普及组] 过河卒
题目见上。
一个经典的递推题
递推不会的看下面:
https://www.cnblogs.com/haoningdeboke-2022/p/16247055.html
俗话输得好 马走日
所以先写出马可以走到的地方
1 const int fx[] = {0, -2, -1, 1, 2, 2, 1, -1, -2}; 2 const int fy[] = {0, 1, 2, 2, 1, -1, -2, -2, -1};
然后标记马走过的地方:
1 for(int i = 1; i <= 8; i++) s[mx + fx[i]][my + fy[i]] = 1;
但要防止越界,所以坐标+2以防越界:
1 bx += 2; by += 2; mx += 2; my += 2;
最关键的代码:
for(int i = 2; i <= bx; i++){ for(int j = 2; j <= by; j++){ if(s[i][j]) continue; // 如果被马拦住就直接跳过 f[i][j] = f[i - 1][j] + f[i][j - 1]; //递推 因为可以从左边的点和上边的点走过来所以 左边的点+上边的点
}
}
完整代码:
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<algorithm> 5 #define ll long long 6 using namespace std; 7 8 const int fx[] = {0, -2, -1, 1, 2, 2, 1, -1, -2}; 9 const int fy[] = {0, 1, 2, 2, 1, -1, -2, -2, -1}; 10 //马可以走到的位置 11 12 int bx, by, mx, my; 13 ll f[40][40]; 14 bool s[40][40]; //判断这个点有没有马拦住 15 int main(){ 16 scanf("%d%d%d%d", &bx, &by, &mx, &my); 17 bx += 2; by += 2; mx += 2; my += 2; 18 //坐标+2以防越界 19 f[2][1] = 1;//初始化 20 s[mx][my] = 1;//标记马的位置 21 for(int i = 1; i <= 8; i++) s[mx + fx[i]][my + fy[i]] = 1; 22 for(int i = 2; i <= bx; i++){ 23 for(int j = 2; j <= by; j++){ 24 if(s[i][j]) continue; // 如果被马拦住就直接跳过 25 f[i][j] = f[i - 1][j] + f[i][j - 1]; 26 //状态转移方程 27 } 28 } 29 printf("%lld\n", f[bx][by]); 30 return 0; 31 }