感觉题目没说清楚,就是那个空格出现的位置,好多玩家似乎都没考虑,比如 A 20; 这种,又或者是 A2 0 ; 空格可能出现的位置题目并没有明确说明,只是在例子中提到,但是好多玩家的解法里似乎都没考虑各种花式的空格插入的可能性,但似乎都过了(是我漏掉什么了吗)。
然后是非法字符,我最开始没看到数字长度最多为2,我以为是任意的整数,导致我的做法考虑得稍微多了点。
这个题 O(N) 的时间足矣,我的做法便是使用字符自动机从左开头扫描到结尾即可完成对这个字符串的分析,便类似一个在线算法,不用先分割,也不需要额外的数组去保存某个子串,向前指针走到到哪便分析到哪。
直接上C语言(含注释):
#include <stdio.h>
#include <ctype.h>
#include <stdbool.h> // 在C中使用bool类型
char buffer[2000]; // 全局缓冲区
int sign; // 决定方向的正负,取+1/-1
int* pxy; // 指向要修改的 x 或者 y (根据按键的方向修改)
char* start; // 开始指针,指向单词的开头
char* forward; // 向前指针,指向单词的结尾
char* cur; // 当前游标位置
bool terminate; // 自动机是否终止
// 自动机启动
void startup()
{
// 指向 buffer 开头的前一个位置
start = forward = cur = buffer - 1;
pxy = NULL;
terminate = false;
}
// 负责获取下一个单词,以及决定自动机是否该停止
void next_word()
{
++forward;
while (*forward == ' ') ++forward; // 跳过下个单词开头的空格
start = forward;
while (*forward != ';') {
if (*forward == '\0') {
terminate = true;
return;
}
++forward;
}
}
// 字符自动机
void automaton(int* x, int* y)
{
startup();
// 每次循环处理一个单词
next_word();
while (!terminate) {
// 如果开头字符不是方向,说明有误,故跳过这个单词
switch (*start) {
case 'A':
sign = -1;
pxy = x;
break;
case 'D':
sign = 1;
pxy = x;
break;
case 'W':
sign = 1;
pxy = y;
break;
case 'S':
sign = -1;
pxy = y;
break;
default:
next_word();
continue;
}
cur = start + 1;
while (*cur == ' ') ++cur; // 跳过空格
if (!isdigit(*cur)) { // 如果方向后跟的不是数字则有误
next_word();
continue;
}
int number = *cur - '0';
while (isdigit(*++cur))
number = number * 10 + (*cur - '0');
while (*cur == ' ') ++cur; // 跳过空格
if (*cur != ';') { // 如果数字后跟的不是分号则有误
next_word();
continue;
}
*pxy += sign * number;
next_word();
}
}
int main()
{
int x, y;
while (scanf("%s", buffer) == 1) {
x = y = 0;
automaton(&x, &y);
printf("%d,%d\n", x, y);
}
return 0;
} 
京公网安备 11010502036488号