【openjudge】Example 3.6 Crossing the River Pawn (Noip2002)

 

【Title description】

There is a river crossing pawn at point A on the chessboard and needs to go to the target point B. The rules of pawn walking: it can go down or to the right. At the same time, there is an opponent's horse (such as point C) at a certain point on the chessboard. The point where the horse is located and all points that can be reached by jumping one step are called the control points of the opponent's horse, such as points C and P1 in Figure 3-1. , ..., P8, pawns cannot pass the control point of the opponent's horse. The chessboard is represented by coordinates, point A (0,0), point B (n, m) (n, m is an integer not exceeding 20), and the position coordinates of the horse also need to be given, C≠A and C≠B . You are now asked to count the number of paths the pawn can take from point A to point B.

【enter】

Give the coordinates of n, m, and C points.

【Output】

The number of paths from point A to point B.

【Input example】
 8  6  0  4
【Example of output】
1617
Input and output example

 

【Analysis of Algorithms:】

The 20*20 grid will time out with dfs, and the scaling should be recursive.

f[i][j] indicates the number of paths from point (0, 0) to point (i, j), vis[i][j] is 1 indicates that point (i, j) is the control point of the horse

Recursion is easily obtained by categorical addition:

  f[i][j] = f[i - 1][j] + f[i][j - 1];

i, j >= 1 、i <= n 、j <= m、vis[i][j] = 0

The more important thing to note is the initialization:

You can't just assign the border point to 1, if there is a control point of the horse on the border, it will be GG..

If this point is a control point for a horse, all points after it cannot be reached

There is a more convenient way to write initialization:

f[0][0] = vis[0][0] ^ 1;
for(int i = 1; i <= m; i++) f[0][i] = f[0][i - 1] ^ vis[0][i];
for(int i = 1; i <= n; i++) f[i][0] = f[i - 1][0] ^ vis[i][0];

 

【Code:】

 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 
 5 const int dx[8] = {2, 2, 1, 1, -2, -2, -1, -1};
 6 const int dy[8] = {1, -1, 2, -2, 1, -1, 2, -2};
 7 
 8 //注意开long long
 9 long long n, m, xc, yc;
10 long long ans, f[21][21];
11 bool vis[21][21];
12 
13 int main() {
14     scanf("%lld%lld%lld%lld", &n, &m, &xc, &yc);
15     vis[xc][yc] = 1;
16     for(int i = 0; i < 8; i++) {
17         int xx = xc + dx[i], yy = yc + dy[i];
18         if(xx <= n && yy <= m && xx >= 0 && yy >= 0)
19             vis[xc + dx[i]][yc + dy[i]] = 1;
20     }
21     f[0][0] = vis[0][0] ^ 1;
22     for(int i = 1; i <= m; i++) f[0][i] = f[0][i - 1] ^ vis[0][i];
23     for(int i = 1; i <= n; i++) f[i][0] = f[i - 1][0] ^ vis[i][0];
24     
25     for(int i = 1; i <= n; i++) {
26         for(int j = 1; j <= m; j++) {
27             if(!vis[i][j])
28                 f[i][j] = f[i - 1][j] + f[i][j - 1];
29         }
30     }
31     printf("%lld\n", f[n][m]);
32 }

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326268548&siteId=291194637