社区讨论
听说水区大佬多
灌水区参与者 2已保存回复 2
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 2 条
- 当前快照
- 1 份
- 快照标识符
- @lxhg6gb4
- 此快照首次捕获于
- 2024/06/16 19:12 2 年前
- 此快照最后确认于
- 2024/06/16 21:42 2 年前
一道站外题
用c++解决下面的问题
题目描述
小T是一个有梦想的小兵。 众所周知,在国际象棋的规则中,小兵走到对面底线后,可以升变为皇后、车等强力棋子,但不能不变。不过小T并不是一个普通的小兵,他理解不了斜吃、吃过路兵等国际象棋的规则,因此他只打算向右或者向下走,并且每次只能移动一个格子。另外,由于某些格子有友方棋子,因此这些格子是不能走的。小T想知道从他现在的位置出发,有几种不同的路线可以升变。
当且仅当两条路线长度一致、路线经过的点集相同、经过这些点的顺序相同,我们才认为这是相同的路线,否则均是不同的路线。
输入格式
第一行一个整数n,m,代表棋盘是n*n的,并且此时还有m个友方棋子(不含小T)。
第二行两个整数x,y,代表小T的位置。
后续m行,每行两个整数ai,bi,代表友方棋子的位置。
棋盘左上角的位置为1,1,右下角的位置为n,n。
输出格式
输出一个整数,代表升变路线的个数。
样例数据
样例输入#1
3 1
1 1
2 2
样例输出#1
2
样例解释: 小T初始位于(1,1),(2,2)格不能走。
可以连续向下走两格升变,或者向右走两格再向下走两格升变。
数据范围
2<=n<=20,0<=m<=5
1<=x,y,ai,bi<=n
保证小T开始不会处于底线,不会有两个棋子在一个位置(小T也算棋子)。
CPP#include <iostream>
#include <vector>
using namespace std;
int n, m;
int xt, yt; // 小T的位置
vector<pair<int, int> > obstacles; // 友方棋子位置
vector<vector<int> > dp; // 用于存储中间结果的动态规划数组
int dfs(int x, int y) {
// 边界情况处理
if (x == n && y == n) {
return 1; // 到达底线,返回一种路线
}
if (x > n || y > n) {
return 0; // 越界,返回0种路线
}
for (int i = 0; i < obstacles.size(); ++i) {
if (x == obstacles[i].first && y == obstacles[i].second) {
return 0; // 遇到友方棋子,返回0种路线
}
}
// 如果之前已经计算过当前位置的结果,则直接返回
if (dp[x][y] != -1) {
return dp[x][y];
}
// 继续向右和向下搜索,并将结果保存在dp中
dp[x][y] = dfs(x + 1, y) + dfs(x, y + 1);
return dp[x][y];
}
int main() {
cin >> n >> m;
cin >> xt >> yt;
dp = vector<vector<int> >(n + 1, vector<int>(n + 1, -1)); // 初始化dp数组为-1
for (int i = 0; i < m; ++i) {
int a, b;
cin >> a >> b;
obstacles.push_back(make_pair(a, b));
}
int result = dfs(xt, yt);
cout << result << endl;
return 0;
}
错了一个点
回复
共 2 条回复,欢迎继续交流。
正在加载回复...