@leean

Как решить задачу на c++?

Условие задачи:
Иван Петрович хранит свои важные документы в сейфе с механическим кодовым замком, который представляет собой поворачивающийся диск с нанесенными на него делениями, каждому из которых назначен порядковый номер, начиная с единицы. Все деления, кроме первого, имеют номер на единицу больший, чем у предыдущего при движении по часовой стрелке. Рядом с диском на сейфе нанесена стрелка, которая указывает на некоторое деление и не сдвигается при повороте диска. Изначально стрелка указывает на первое деление. При наборе кода Иван Петрович несколько раз повторяет комбинацию из двух поворотов: сначала поворачивает диск на A делений против часовой стрелки (стрелка на сейфе «перемещается» относительно диска по часовой стрелке), затем на B делений в обратную сторону. Определите, сколько раз повторяется эта комбинация поворотов, если стрелка на сейфе указывала на последнее N-е деление, то есть «проходила» мимо него или меняла свое направление на нем, K раз.

Примеры тестов:
1 3 5 0
ответ: 0

1 2 4 2
ответ: 2

2 3 3 1
ответ: -1

Если кто-то знает как это можно решить максимально рационально, прошу расскажите способ решения(алгоритм)
не прошу код!
  • Вопрос задан
  • 260 просмотров
Пригласить эксперта
Ответы на вопрос 1
@Elsper
Если код не важен, а нужно именно решение, то вот на привычном для меня C#
Идея в том, что мы просто симулируем поворот замка и смотрим что происходит.

int A = 2;
int B = 3;
int N = 3;
int K = 1;

int maxPos = N;
int currentPos = 1;

int countReachK = 0;
int countPairs = 0;

while (countReachK < K)
{
    //Если надо приводим к нулю чтобы не считать пересечение два раза.
    if ((currentPos == maxPos) && (A>0)) 
    currentPos = 0;

    currentPos += A;

    //Проверка на пересечение или остановку.
    while (currentPos >= maxPos)
    {
        currentPos -= maxPos;
        countReachK++;
    }

    //Если надо приводим к максимуму чтобы не считать пересечение два раза.
    if ((currentPos == 0) && (B>0)) 
    currentPos = maxPos;

    currentPos -= B;

    //Проверка на пересечение или остановку.
    while (currentPos <=0)
    {
        currentPos += maxPos;
        countReachK++;
    }

    countPairs++;
}
if (countReachK != K)
    countPairs = -1;

// countPairs и есть искомый результат.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы