1 条题解
-
0
第三部分:题目分析与标准代码
1. 解题思路
- 模拟过程:依次读取每条指令,更新 或 的值。
- 纬度处理:
- 纬度是“有界”的,类似于在墙角走路,撞墙就停。
- 使用
if (x > 90) x = 90;和if (x < -90) x = -90;进行修正。
- 经度处理:
- 经度是“循环”的,类似于在圆环上走路。
- 向东 (E):
y += val。如果y > 180,则y -= 360。 - 向西 (W):
y -= val。如果y <= -180,则y += 360。 - 注意:虽然题目中 ,通常一次
if就够了,但为了严谨性(防止多圈),建议使用while循环进行修正。
2. 标准代码 (C++14)
/** * 题目:航海家的坐标 (The Navigator's Coordinates) * 难度:GESP 4级 * 知识点:模拟、边界判断、循环修正 */ #include <iostream> using namespace std; int main() { // 提升 IO 效率 ios::sync_with_stdio(false); cin.tie(NULL); int N; int x, y; // x: 纬度, y: 经度 // 读入 N 和初始坐标 if (!(cin >> N >> x >> y)) return 0; for (int i = 0; i < N; ++i) { char dir; int val; cin >> dir >> val; if (dir == 'N') { x += val; // 纬度北界处理:不能超过 90 if (x > 90) x = 90; } else if (dir == 'S') { x -= val; // 纬度南界处理:不能低于 -90 if (x < -90) x = -90; } else if (dir == 'E') { y += val; // 经度向东跨越处理:范围 (-180, 180] // 如果大于 180,减去 360 while (y > 180) { y -= 360; } } else if (dir == 'W') { y -= val; // 经度向西跨越处理 // 如果小于等于 -180,加上 360 while (y <= -180) { y += 360; } } } cout << x << " " << y << endl; return 0; }
第四部分:数据生成器
这是用于生成
1.in~10.in及其对应标准答案的生成器代码。/** * GESP 4级 [航海家的坐标] - 数据生成器 */ #include <iostream> #include <fstream> #include <vector> #include <string> #include <cstdlib> #include <ctime> using namespace std; // ------------------------------------------ // 标准解法函数 (生成 .out) // ------------------------------------------ void solve(int N, int x, int y, const vector<pair<char, int>>& ops, ofstream& fout) { for (auto op : ops) { char dir = op.first; int val = op.second; if (dir == 'N') { x += val; if (x > 90) x = 90; } else if (dir == 'S') { x -= val; if (x < -90) x = -90; } else if (dir == 'E') { y += val; while (y > 180) y -= 360; } else if (dir == 'W') { y -= val; while (y <= -180) y += 360; } } fout << x << " " << y << endl; } // 辅助函数 int randRange(int min, int max) { return rand() % (max - min + 1) + min; } char randDir() { char dirs[] = {'N', 'S', 'E', 'W'}; return dirs[rand() % 4]; } int main() { srand(time(0)); cout << "Start generating data..." << endl; for (int i = 1; i <= 10; ++i) { string in_name = to_string(i) + ".in"; string out_name = to_string(i) + ".out"; ofstream fin(in_name); ofstream fout(out_name); int N, x0, y0; vector<pair<char, int>> ops; // 构造测试点 if (i == 1) { // 样例 1 N = 3; x0 = 0; y0 = 170; ops = {{'E', 20}, {'N', 100}, {'E', 10}}; } else if (i == 2) { // 样例 2 N = 2; x0 = 0; y0 = -170; ops = {{'W', 20}, {'S', 100}}; } else if (i == 3) { // 极点阻挡测试 N = 2; x0 = 80; y0 = 0; ops = {{'N', 20}, {'N', 20}}; // 应该停在 90 } else if (i == 4) { // 日界线反复横跳 N = 4; x0 = 0; y0 = 179; ops = {{'E', 2}, {'W', 2}, {'E', 2}, {'W', 2}}; } else if (i == 5) { // 刚好 -180 边界测试 N = 1; x0 = 0; y0 = -170; ops = {{'W', 10}}; // -180 -> 180 } else if (i == 6) { // 大数值绕圈 (经度) N = 1; x0 = 0; y0 = 0; ops = {{'E', 360}}; // 应该回到 0 } else if (i == 7) { // 混合随机小数据 N = 10; x0 = 0; y0 = 0; for(int k=0; k<N; k++) ops.push_back({randDir(), randRange(1, 50)}); } else if (i == 8) { // 纯经度移动 N = 20; x0 = 45; y0 = 0; for(int k=0; k<N; k++) { char d = (rand()%2) ? 'E' : 'W'; ops.push_back({d, randRange(10, 100)}); } } else if (i == 9) { // 纯纬度移动 N = 20; x0 = 0; y0 = 100; for(int k=0; k<N; k++) { char d = (rand()%2) ? 'N' : 'S'; ops.push_back({d, randRange(10, 100)}); } } else { // 大规模随机 N = 1000; x0 = randRange(-90, 90); y0 = randRange(-179, 180); for(int k=0; k<N; k++) ops.push_back({randDir(), randRange(1, 360)}); } // 写入输入 fin << N << " " << x0 << " " << y0 << endl; for(auto op : ops) { fin << op.first << " " << op.second << endl; } // 写入输出 solve(N, x0, y0, ops, fout); fin.close(); fout.close(); cout << "Generated Case " << i << endl; } cout << "Done!" << endl; return 0; }
- 1
信息
- ID
- 19276
- 时间
- 1000ms
- 内存
- 32MiB
- 难度
- 10
- 标签
- (无)
- 递交数
- 1
- 已通过
- 1
- 上传者