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 } 

 












 

posted @ 2022-10-16 20:21  傲来国国王  阅读(48)  评论(0编辑  收藏  举报