题目描述
棋盘上AA点有一个过河卒,需要走到目标BB点。卒行走的规则:可以向下、或者向右。同时在棋盘上CC点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒”。
棋盘用坐标表示,AA点(0, 0)(0,0)、BB点(n, m)(n,m)(nn, mm为不超过2020的整数),同样马的位置坐标是需要给出的。
现在要求你计算出卒从AA点能够到达BB点的路径的条数,假设马的位置是固定不动的,并不是卒走一步马走一步。
输入输出格式
输入格式:
一行四个数据,分别表示BB点坐标和马的坐标。
输出格式:
一个数据,表示所有的路径条数。
【题目提示了结果可能很大,疯狂暗示long long】
一开始想就20*20的格子,非常快的写了bfs,愉快地TLE。再次明白男人的直觉不可信,递推了一下式子。
F[x][y]= F[x- 1][y]+ F[x][y- 1];
很明眼的关系,就不费话了。
#include#include #include using namespace std;bool box[22][22];void into(int a, int b){ for (int j = 0; j <= 20; j ++) { for (int k = 0; k <= 20; k ++) { box[j][k]= false; } } box[a][b]= true; if (a- 2>= 0) { if (b- 1>= 0) { box[a- 2][b- 1]= true; } if (b+ 1<= 20) { box[a- 2][b+ 1]= true; } } if (a+ 2<= 20) { if (b- 1>= 0) { box[a+ 2][b- 1]= true; } if (b+ 1<= 20) { box[a+ 2][b+ 1]= true; } } if (b- 2>= 0) { if (a- 1>= 0) { box[a- 1][b- 2]= true; } if (a+ 1<= 20) { box[a+ 1][b- 2]= true; } } if (b+ 2<= 20) { if (a- 1>= 0) { box[a- 1][b+ 2]= true; } if (a+ 1<= 20) { box[a+ 1][b+ 2]= true; } }}long long f[22][22];int main(){ int x, y, a, b; while (cin >> x >> y >> a >> b) { into(a, b); for (int j = 0; j <= x; j ++) { for (int k = 0; k <= y; k ++) { f[j][k]= 0; } } f[0][0]= 1; for (int j = 0; j <= x; j ++) { for (int k = 0; k <= y; k ++) { if (! box[j][k]) { f[j+ 1][k]+= f[j][k]; f[j][k+ 1]+= f[j][k]; } } }// for (int j = 0; j <= x; j ++)// {// for (int k = 0; k <= y; k ++)// {// printf("%4d", box[j][k]);// }// printf("\n");// }// printf("###############################\n");// for (int j = 0; j <= x; j ++)// {// for (int k = 0; k <= y; k ++)// {// printf("%4d", f[j][k]);// }// printf("\n");// } cout << f[x][y] << endl; } return 0;}
bfs既然写了也丢着吧。
#include#include #include using namespace std;bool box[22][22];void into(int a, int b){ box[a][b]= true; if (a- 2>= 0) { if (b- 1>= 0) { box[a- 2][b- 1]= true; } if (b+ 1<= 20) { box[a- 2][b+ 1]= true; } } if (a+ 2<= 20) { if (b- 1>= 0) { box[a+ 2][b- 1]= true; } if (b+ 1<= 20) { box[a+ 2][b+ 1]= true; } } if (b- 2>= 0) { if (a- 1>= 0) { box[a- 1][b- 2]= true; } if (a+ 1<= 20) { box[a+ 1][b- 2]= true; } } if (b+ 2<= 20) { if (a- 1>= 0) { box[a- 1][b+ 2]= true; } if (a+ 1<= 20) { box[a+ 1][b+ 2]= true; } }}bool Is_out_box (pair p, int x, int y){ if (p.first < 0 || p.first > x ) return true; if (p.second < 0 || p.second > y ) return true; return false;}queue >q;int main(){ int x, y, a, b; while (cin >> x >> y >> a >> b) { for (int j = 0; j <= 20; j ++) { for (int k = 0; k <= 20; k ++) { box[j][k]= false; } } into(a, b); int cnt = 0; while (! q.empty()) q.pop(); pair p1 (0, 0); pair p2, p3; q.push(p1); while (! q.empty()) { p2= q.front(); q.pop();// printf("%d -- %d\n", p2.first, p2.second); while (p2.first == x&& p2.second== y) { cnt ++; if (! q.empty() )p2= q.front(), q.pop(); else break; } for (int c = 0; c < 2; c ++) { if (! c) p3.first= p2.first+ 1, p3.second= p2.second; else p3.first= p2.first, p3.second= p2.second+ 1; if (! box[p3.first][p3.second]&& ! Is_out_box(p3, x, y) ) q.push(p3); } } cout << cnt << endl; } return 0;}