博主头像

ワクワク

2025/07/25 HJ15 坐标移动

描述

我们定义一个无限大的二维网格上有一个小人,小人初始位置为 (0,0)(0,0) 点,小人可以读取指令上下左右移动。一个合法的指令由三至四个符号组成:

第一个符号为 "A/D/W/S"中的一个,代表小人移动的方向;分别代表向左、向右、向上、向下移动;记某个时刻小人的坐标为 (x,y)(x,y),向左移动一格即抵达(x−1,y)、向右移动一格即抵达(x+1,y)、向上移动一格即抵达(x,y+1)、向下移动一格即抵达 (x,y−1)。

最后一个符号为 ‘;’,代表指令的结束,该符号固定存在;中间为一个大于 00 且小于 100 的数字,代表小人移动的距离。特别地,如果这个数字小于 1010,那么它可能包含一个前导零,此时也视为合法。

如果你遇到了一个不合法的指令,则直接忽略;例如,指令 "A100;" 是不合法的,因为 100超出了规定的数字范围;"Y10;" 也是不合法的,因为 YY 不是 "A/D/W/S" 中的一个。

输出小人最终的坐标。

输入描述:

在一行上输入一个长度 1≦length(s)≦104,由大写字母、数字和分号(‘;’)构成的字符串 s,代表输入的指令序列。保证字符串中至少存在一个 ‘;’,且末尾一定为 ‘;’。

输出描述:

在一行上输出一个两个整数,代表小人最终位置的横纵坐标,使用逗号间隔。

示例1

输入:A10;S20;W10;D30;X;A1A;B10A11;;A10;

输出:10,-10

说明:

对于这个样例,我们模拟小人的移动过程:

  • 第一个指令 "A10;""A10;" 是合法的,向左移动 1010 个单位,到达 (−10,0)(−10,0) 点;
  • 第二个指令 "S20;""S20;" 是合法的,向下移动 2020 个单位,到达 (−10,−20)(−10,−20) 点;
  • 第三个指令 "W10;""W10;" 是合法的,向上移动 1010 个单位,到达 (−10,−10)(−10,−10) 点;
  • 第四个指令 "D30;""D30;" 是合法的,向右移动 3030 个单位,到达 (20,−10)(20,−10) 点;
  • 第五个指令 "X;""X;" 不合法,跳过;
  • 第六个指令 "A1A;""A1A;" 不合法,跳过;
  • 第七个指令 "B10A11;""B10A11;" 不合法,跳过;
  • 第八个指令 ";"";" 不合法,跳过;
  • 第九个指令 "A10;""A10;" 是合法的,向左移动 1010 个单位,到达 (10,−10)(10,−10) 点。

##示例2

输入:ABC;AKL;DA1;D001;W023;A100;S00;

输出:0,0

说明:在这个样例中,全部指令均不合法,因此小人不移动。

示例3

输入:A00;S01;W2;

输出:0,1

思路

分为三个模块

第一个模块将输入字符串分割,采用双指针识别,i指向位移长度开头,默认为1(i-1为位移方向),j指向‘;’

第二个模块为单独函数,导入字符串和双指针,将char型位移长度转为int型

第三个模块用Switch判断位移方向,ASWD则计算坐标变化,否则跳过

题解

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
    char *str = (char *)malloc(10000);
    char direction;
    int step_size = 0;
    int i = 1, j;
    int x = 0, y = 0;
    scanf("%s", str); // 去掉\n,避免读取换行符的问题
    for(j = 0; j <= strlen(str); j++) {
        if (str[j] == ';') {
            direction = str[i - 1];
            if ((j - i) < 5) { // 指令长度不超过4
                step_size = judgeNum(str, i, j);
                switch (direction) {
                    case 'A': x -= step_size; break;
                    case 'D': x += step_size; break;
                    case 'W': y += step_size; break;
                    case 'S': y -= step_size; break;
                    default: break;
                }
            }
            i = j + 2; // 更新i到下一个指令的开始
        }
    }
    printf("%d,%d\n", x, y);
    free(str); // 释放内存
    return 0;
}
int judgeNum(char *str, int i, int j) {
    int num = 0;
    int k;
    for (k = i; k < j; k++) {
        if(str[k] >= '0' && str[k] <= '9') {
            num = num * 10 + (str[k] - '0');
        } else {
            return 0; // 遇到非数字字符,返回0
        }
    }
    return num;
}
2025/07/25 HJ15 坐标移动
https://blog.minliny.com/index.php/archives/7/
本文作者 Minliny
发布时间 2025-07-25
许可协议 CC BY-NC-SA 4.0
发表新评论