n коров
Фермера Джона выстроены в ряд. i-ая корова слева имеет метку i (1 ≤ i ≤ n). Фермер Джон приказал коровам повторить ровно k раз следующий двухшаговый
процесс:
·
Последовательность
коров в позициях a1, …, a2 слева реверсивно меняют свой порядок. Затем
последовательность коров в позициях b1, …, b2 слева реверсивно меняют свой порядок.
Выведите получившийся порядок коров для всех i (1 ≤ i ≤ n) после выполнения этого процесса ровно k раз.
Вход. Первая
строка содержит n (1 ≤ n ≤ 100) и k (1 ≤ k ≤ 109).
Вторая строка содержит a1 и a2 (1 ≤ a1 < a2 ≤ n). Третья строка содержит b1 и b2 (1 ≤ b1 < b2 ≤ n).
Выход. В i-ой строке
выведите метку i-ой коровы
слева после завершения процесса всех обменов.
Пояснение. Изначально порядок коров [1, 2, 3, 4, 5, 6, 7] слева
направо. После первого шага преобразования порядок станет [1, 5, 4, 3, 2, 6, 7].
После второго шага преобразования порядок станет [1, 5, 7, 6, 2, 3, 4].
Повторение обоих шагов второй раз даст ответ.
Пример входа |
Пример выхода |
7 2 2 5 3 7 |
1 2 4 3 5 7 6 |
моделирование
Анализ алгоритма
Если моделировать процесс перестановки коров, то получим
Time
Limit, так как число повторов двухшагового
процесса k
≤ 109 слишком
велико.
Расставим коров по порядку на позиции от 1 до n.
Для каждой коровы номер i
(1 ≤ i ≤ n) найдем
позицию, в которой она окажется через k итераций. Для каждой коровы найдем
число итераций p, через которое она снова
будет занимать исходное место. Это число p ≤ n ≤ 100 не велико. Тогда
эта корова займет исходное место через 2p, 3p, 4p … итераций.
Через k – (k % p)
итераций рассматриваемая корова снова
окажется на своем исходном месте (так как указанное число делится на p). Остается совершить еще k % p итераций
чтобы найти конечное положение коровы.
Пример
Изначальный порядок коров имеет вид:
Шаг 1
Шаг 2
Объявим
массив pos. Если корова
номер i после k итераций займет позицию cur, то присвоим pos[cur] = i.
int pos[101];
Пусть некоторая корова
находится в позиции x. Функция nex(x) возвращает
позицию этой коровы после двухшагового процесса. Если корова находится в позиции
x, которая принадлежит отрезку [a1; a2], то после его переворачивания корова переместится в позицию
a1 + a2 – x.
int nex(int x)
{
if (a1 <= x && x <= a2) x = a1 + a2 - x;
if (b1 <= x && x <= b2) x = b1 + b2 - x;
return x;
}
Основная часть
программы. Читаем входные данные.
scanf("%d %d", &n, &k);
scanf("%d %d", &a1, &a2);
scanf("%d %d", &b1, &b2);
Для каждой коровы
номер i находим ее положение после
выполнения процесса всех обменов.
for (i = 1; i <= n; i++)
{
В переменной p находим количество итераций (одна итерация есть выполнение
двухшагового процесса один раз), через которое i-ая корова снова окажется на своем месте. Переменная cur содержит текущую позицию коровы.
p = 1; cur = nex(i);
Выполняем цикл пока i-ая корова не станет на свое начальное место – позицию
номер i.
while (cur != i)
{
p++;
cur = nex(cur);
}
Через k – (k % p) итераций
i-ая корова снова окажется на i-ом месте. Проведем еще k % p итераций
для нахождения финального месторасположения i-ой коровы.
kk = k % p;
for (j = 0; j <
kk; j++)
cur = nex(cur);
Корова номер i после k
итераций займет позицию cur.
pos[cur] = i;
}
Выводим конечное
расположение коров после завершения всех обменов.
for (i = 1; i <= n; i++)
printf("%d\n", pos[i]);
В случае
непосредственного моделирования операций из-за ограничения k ≤ 109 получаем Time Limit.
#include <cstdio>
#include <algorithm>
using namespace std;
int i, n, k, a1, a2, b1, b2;
int m[101];
int main(void)
{
scanf("%d
%d", &n, &k);
scanf("%d
%d", &a1, &a2);
scanf("%d
%d", &b1, &b2);
for (i = 1; i <=
n; i++)
m[i] = i;
for (i = 0; i <
k; i++)
{
reverse(m + a1, m + a2 +
1);
reverse(m + b1, m + b2 +
1);
}
for (i = 1; i <=
n; i++)
printf("%d\n", m[i]);
return 0;
}