Я решил проблему онлайн-судьи (входные данные верны), однако мой алгоритм слишком медленный.
У меня есть матрица переменных размеров, и я хочу найти координатыn
количество квадратов пройдено . В этом примере размер матрицы: 8
. Значение количества строк и столбцов.
![enter image description here](https://i.stack.imgur.com/fhAbp.png)
Начиная с точки x, y
: (1, 1) и;
- Как можно дальше вправо насколько возможно
- Как далеко вниз насколько возможно
- Как далеко влево насколько это возможно
- Как можно дальше вверх насколько возможно
Учитывая, что i = 53
Начиная с n = 0
и добавляя 1
кn
для каждого пройденного квадрата, достигнув n == i
, вычислите координаты.
Что я пробовал:
(Отказ от ответственности: я только публикую это такВы можете видеть, насколько я наивен)
В моей первоначальной задаче программирования я достиг ее путем создания переменной m
с размером матрицы, как в данном случае m = 8
, и выведения ее после каждого right
и left
движений .
y = 0 //y will move first, starts offboard at imaginary column `0`
x = 1 //start from row 1
m = 8
right: { y+= i; m -= 1;} //x = 1, y = 8 / m = 7
down: { x+= m; }//x = 8, y = 8
left: { y-= m; m -= 1; } //x = 8, y = 1 / m = 6
up: { x-=m; } // x = 2, y = 1
И итерация, пока другая созданная переменная sumofsteps
, суммирует количество пройденных m
квадратов i
, которыев этом case 53
. ''
Это, конечно, очень наивно, поскольку в некоторых случаях матрица может быть такой большой, как 1073741824
и количество шагов 1152921504603393520
, которое в моей программе занимает слишком многодолго решать.
Ограничение времени выполнения программы составляет 1,0 секунды для одного входа.
Есть ли более быстрый способ найти координаты?
#include <iostream>
#include <sstream>
void GetSpiralFinalCoordinates(
const unsigned long long gridSize,
const unsigned long long finalDestSteps,
unsigned long long& x, unsigned long long& y)
{
x = 1;
y = 0;
unsigned long long stepsWalked{0};
unsigned long long currentStepsToWalk = gridSize;
enum movedir {RIGHT = 0, DOWN, LEFT, UP};
while(stepsWalked < finalDestSteps)
{
for(int i=0; i<4; i++)
{
if(stepsWalked + currentStepsToWalk < finalDestSteps)
{
stepsWalked += currentStepsToWalk;
switch(i)
{
case RIGHT: { y+= currentStepsToWalk; currentStepsToWalk -= 1;}break;
case DOWN: { x+= currentStepsToWalk; }break;
case LEFT: { y-= currentStepsToWalk; currentStepsToWalk -= 1; }break;
case UP: { x-=currentStepsToWalk; }break;
}
} else {
int lastAmountOfStepsToWalk = finalDestSteps - stepsWalked;
switch(i)
{
case RIGHT: { y+= lastAmountOfStepsToWalk; }break;
case DOWN: { x+= lastAmountOfStepsToWalk; }break;
case LEFT: { y-= lastAmountOfStepsToWalk; }break;
case UP: { x-=lastAmountOfStepsToWalk; }break;
}
stepsWalked = finalDestSteps + 1;
break;
}
}
}
}
int main()
{
unsigned long long x, y;
unsigned long long a, b;
std::string line;
std::getline(std::cin, line);
std::istringstream issline(line);
issline >> a;
issline >> b;
GetSpiralFinalCoordinates(a,b, x, y);
std::cout << x << " " << y << std::endl;
}