У меня проблема с головоломкой под названием «Детская игра » из Codinggame. Я пишу на машинописном языке!
Заявление:
Вот уже несколько лет в начальных школах мы наблюдаем появление новой образовательной модели — игрового программирования. Студенты должны запрограммировать маленького робота, используя сборочные блоки. Это позволяет им знакомиться с программированием с раннего возраста, тренируя свою логику и восприятие пространства.
Вы учитесь в одной из таких школ. Цель упражнения проста: ваш учитель построил схему для вашего робота, сказал вам, сколько ходов может сделать робот, а вы должны узнать конечное положение робота в конце выполнения.
Для этого нужно знать некоторые принципы работы робота.
– Когда робот сталкивается с препятствием (обозначается #), он поворачивает направо (в той же операции) до тех пор, пока впереди не исчезнет препятствие. В противном случае на пустой области (обозначенной .) он движется прямо вперед.
– Робот изначально движется вверх.
– Робот останавливается после n ходов.
- Верхний левый угол представляет собой координаты (0,0)
– Окружающая среда робота представлена следующим образом, где O – начальное положение робота:
...#........
...........#
............
............
..#О........
..........#.
Я заблокирован на тесте 4, потому что мое решение не оптимизировано.
В консоли выдает: Время ожидания процесса истекло. Это может означать, что ваше решение недостаточно оптимизировано для обработки некоторых случаев.
Я попытался изменить цикл на цикл «пока», а также изменить и изменить условие «переключатель» на условие «если-иначе».
Можете ли вы помочь мне найти лучшее решение или другой способ проведения тестов?
var inputs: string[] = readline().split(' ');
const w: number = parseInt(inputs[0]);
const h: number = parseInt(inputs[1]);
const n: number = parseInt(readline());
let zone: string[][] = [];
let robot: robot = { x: 0, y: 0 };
interface robot {
x: number,
y: number
}
for (let i = 0; i < h; i++) {
const line: string = readline();
zone = [...zone, line.split('')]
}
zone.forEach((line, y) => {
line.forEach((place, x) => {
if (place === "O") {
robot.x = x;
robot.y = y;
}
})
})
function getLoc(robot: robot, zone: string[][], tours: number) {
let direct: string = "T";
var i = 0;
while (i < tours) {
if (direct === "T") {
if (zone[robot.y - 1][robot.x] === '#') {
robot.x++;
direct = "R";
} else {
robot.y--;
}
} else if (direct === "R") {
if (zone[robot.y][robot.x + 1] === '#') {
robot.y++;
direct = "B";
} else {
robot.x++;
}
} else if (direct === "B") {
if (zone[robot.y + 1][robot.x] === '#') {
robot.x--;
direct = "L";
} else {
robot.y++;
}
} else if (direct === "L") {
if (zone[robot.y][robot.x - 1] === '#') {
robot.y--;
direct = "T";
} else {
robot.x--;
}
}
i++;
}
return robot
}
console.time("getLoc")
let res: robot = getLoc(robot, zone, n);
console.timeEnd("getLoc")
console.info(`${res.x} ${res.y}`)
Робот войдет в петлю.
Вы должны выяснить, какова длина цикла, сколько раз он проходит через него, а затем завершить последний неполный цикл.
Я рекомендую, чтобы объект сообщал, когда он последний раз находился в данной позиции и ориентации. Когда вы обнаружите, что оно повторяется, вы теперь знаете длину цикла и можете перепрыгнуть через повторяющееся поведение.
спасибо за ваши советы, они мне помогли в решении проблемы! Я изменил структуру основного кода, добавил три функции: getSteps() для получения оставшихся ходов и определения наличия цикла, moveRobot() для перемещения робота и получения всех ходов. getLoc(), чтобы получить окончательную позицию с результатом getSteps(). Дохожу до 8-го теста, но на 9-м заблокирован. Ответ "1 3", но я получаю "2 4"! Я не знаю, как решить эту проблему, не сломав остальные.
Карта это:
#####
#...#
#.#.#
#...#
##O##
Код:
var inputs: string[] = readline().split(' ');
const w: number = parseInt(inputs[0]);
const h: number = parseInt(inputs[1]);
const n: number = parseInt(readline());
let zone: string[][] = [];
let robot: robot = { x: 0, y: 0 };
let startRobot: startRobot = { x: 0, y: 0, loops: 1, steps: 0 };
interface startRobot extends robot {
loops: number,
steps: number
}
interface robot {
x: number,
y: number
}
for (let i = 0; i < h; i++) {
const line: string = readline();
zone = [...zone, line.split('')]
console.error(line)
}
zone.forEach((line, y) => {
line.forEach((place, x) => {
if (place === "O") {
robot.x = x;
robot.y = y;
startRobot.x = x;
startRobot.y = y;
}
})
})
function getSteps(robot: robot, zone: string[][], steps: number, start: startRobot) {
let direct: string = "T";
var i: number = 0;
var s: number = 0;
let quotient: number = 0;
let newSteps: number = 0;
while (i < steps) {
let resfunction = moveRobot(direct, zone, robot);
robot = resfunction.robot;
direct = resfunction.direct;
i++;
start.steps++;
if (robot.x === start.x && robot.y === start.y) {
s++;
}
if (s === start.loops) {
quotient = steps / start.steps;
newSteps = steps - start.steps * (Math.floor(quotient) - 1);
break;
}
}
return newSteps
}
function moveRobot(direct: string, zone: string[][], robot: robot) {
if (direct === "T") {
if (robot.y - 1 >= zone.length) {
if (zone[robot.y][robot.x] === '#') {
robot.x++;
direct = "R";
} else {
robot.y--;
}
} else {
if (zone[robot.y - 1][robot.x] === '#') {
robot.x++;
direct = "R";
} else {
robot.y--;
}
}
} else if (direct === "R") {
if (robot.x + 1 >= zone[0].length) {
if (zone[robot.y][robot.x] === '#') {
robot.y++;
direct = "B";
} else {
robot.x++;
}
} else {
if (zone[robot.y][robot.x + 1] === '#') {
robot.y++;
direct = "B";
} else {
robot.x++;
}
}
} else if (direct === "B") {
if (robot.y + 1 >= zone.length) {
if (zone[robot.y][robot.x] === '#') {
robot.x--;
direct = "L";
} else {
robot.y++;
}
} else {
if (zone[robot.y + 1][robot.x] === '#') {
robot.x--;
direct = "L";
} else {
robot.y++;
}
}
} else if (direct === "L") {
if (robot.x - 1 >= zone[0].length) {
if (zone[robot.y][robot.x] === '#') {
robot.y--;
direct = "T";
} else {
robot.x--;
}
} else {
if (zone[robot.y][robot.x - 1] === '#') {
robot.y--;
direct = "T";
} else {
robot.x--;
}
}
}
return { direct, robot }
}
function getLoc(robot: robot, zone: string[][], steps: number, start: startRobot) {
let direct: string = "T";
var i: number = 0;
while (i < steps) {
let resfunction = moveRobot(direct, zone, robot);
robot = resfunction.robot;
direct = resfunction.direct;
i++;
}
return robot
}
// console.time("getLoc")
let newSteps: number = getSteps(robot, zone, n, startRobot);
let res: robot = getLoc(robot, zone, newSteps, startRobot);
// console.timeEnd("getLoc")
console.info(`${res.x} ${res.y}`)
Ваш алгоритм имеет временную сложность, линейную в зависимости от количества ходов. Невозможно выполнить 2 ^ 53 операции за разумное время.