洛谷B3702 [语言月赛202301] 华小科的旅行开始了
代码特点直接根据转移规则模拟路径,逻辑简单。通过二维数组快速查询下一步坐标。潜在问题数组越界:若转移后的坐标nextx或nexty超出有效范围(如nextx > n或nexty > m),会导致访问越界。未初始化区域travel数组的第 0 行和第 0 列未填充数据,可能被错误访问。适用场景题目保证转移路径最终指向(0, 0),且不会越界。若数据存在循环或无效坐标,代码可能无法终止或崩溃
·
原理
问题目标:模拟华小科按照给定的转移规则在二维网格中移动的路径,直到无法继续移动为止。
- 每个位置
(Tx, Ty)对应一个转移规则,存储在二维数组travel中。 travel[Tx][2*Ty-1]表示下一个位置的横坐标,travel[Tx][2*Ty]表示纵坐标。- 当转移坐标为
(0, 0)时,停止移动。
步骤
- 输入初始化:
- 读取网格参数
m(列数)、n(行数),以及初始位置(Sx, Sy)。 - 初始化一个
(n+1) x (2m+1)的二维数组travel,存储转移规则。
- 读取网格参数
- 填充转移规则:
- 按行读取转移规则,每行有
2m个整数,表示每个位置的转移坐标。
- 按行读取转移规则,每行有
- 模拟移动:
- 从初始位置
(Sx, Sy)开始,输出当前位置。 - 根据当前坐标查询
travel数组,计算下一个坐标。 - 若下一个坐标为
(0, 0),停止;否则更新当前位置并重复。
- 从初始位置
图示法表示步骤(示例:m=1, n=2, Sx=1, Sy=1)
- 输入转移规则:
travel[1][1] = 2, travel[1][2] = 1 travel[2][1] = 0, travel[2][2] = 0 - 模拟过程:
- 初始位置
(1, 1),输出1 1。 - 查表得下一位置为
(2, 1),输出2 1。 - 查表得下一位置为
(0, 0),停止。
- 初始位置
代码关键行注释
vector<vector<int>> travel(n+1, vector<int>(2*m+1, 0));
// 初始化 (n+1) 行、(2m+1) 列的二维数组,默认值 0
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= 2*m; j++) {
cin >> travel[i][j];
}
}
// 读取转移规则,填充 travel 数组的第 1~n 行
int nextx = travel[Tx][2*Ty - 1];
int nexty = travel[Tx][2*Ty];
// 根据当前坐标 (Tx, Ty),计算下一个坐标
if (nextx == 0 && nexty == 0) break;
// 终止条件:下一坐标为 (0, 0)
完整代码程序
#include <iostream>
#include <vector>
using namespace std;
int main(){
int m,n,Sx,Sy;
cin>>m>>n>>Sx>>Sy;
vector<vector<int>> travel(n+1,vector<int>(2*m+1,0));
for(int i=1;i<=n;i++){
for(int j=1;j<=2*m;j++){
cin>>travel[i][j];
}
}
int Tx=Sx,Ty=Sy;
cout<<Tx<<" "<<Ty<<endl;
while(1){
int nextx=travel[Tx][2*Ty-1];
int nexty=travel[Tx][2*Ty];
if(nextx==0&&nexty==0) break;
Tx=nextx;
Ty=nexty;
cout<<Tx<<" "<<Ty<<endl;
}
return 0;
}
时间复杂度
- 时间复杂度:O(K),其中 K 是移动路径的长度。每次移动只需查表操作,时间复杂度为 O(1)。
- 空间复杂度:O(n*m),用于存储
travel数组。
总结
- 代码特点:
- 直接根据转移规则模拟路径,逻辑简单。
- 通过二维数组快速查询下一步坐标。
- 潜在问题:
- 数组越界:若转移后的坐标
nextx或nexty超出有效范围(如nextx > n或nexty > m),会导致访问越界。 - 未初始化区域:
travel数组的第 0 行和第 0 列未填充数据,可能被错误访问。
- 数组越界:若转移后的坐标
- 适用场景:
- 题目保证转移路径最终指向
(0, 0),且不会越界。 - 若数据存在循环或无效坐标,代码可能无法终止或崩溃。
- 题目保证转移路径最终指向
更多推荐



所有评论(0)