Я ищу для решения этой задачи:Найти число возможных комбинаций три перестановки списков
Есть три переставляются целые списки:
index
0 1 2 3
[2,4,3,1]
[3,4,1,2]
[1,2,4,3]
Я хотел бы знать, сколько комбинации из трех кортежей по спискам. Например, после поворота второго списка по одному справа и третьего списка один слева:
0 1 2 3
[2,4,3,1]
3 0 1 2
[2,3,4,1]
1 2 3 0
[2,4,3,1]
приведет в двух комбинациях (2,2,2)
и (1,1,1)
. Меня интересует только количество комбинаций, а не самих комбинаций.
списков всегда имеют одинаковую длину N. Из моего понимания, есть по меньшей мере одна комбинации и максимально Н.
Я написал императивное решение, используя три вложенные для петель, но для больших проблем (например, N> 1000) это быстро становится невыносимым.
Есть ли более эффективный подход, чем грубая сила (попытка всех комбинаций) ?. Может быть, какой-то умный алгоритм или математический трюк?
Edit:
Я перефразировать вопрос, чтобы сделать это (надеюсь) более ясно:
У меня есть 3 перестановки списка [1..n].
Списки могут быть индивидуально повернуты влево или вправо, пока элементы для некоторых индексов не совпадут. В приведенных выше примере это будет:
список правого поворота 2 на 1
левого списка 3 вращения 1
Теперь столбцы совмещены для 2 и 1.
Я также добавил индексы в приведенном выше примере. Скажите, пожалуйста, если это еще неясно.
Мой код до сих пор:
#include <iostream>
int
solve(int n, int * a, int * b, int * c)
{
int max = 0;
for (int i = 0; i < n; ++i) {
int m = 0;
for (int j = 0; j < n; ++j) {
if (a[i] == b[j]) {
for (int k = 0; k < n; ++k) {
if (a[i] == c[k]) {
for (int l = 0; l < n; ++l) {
if (a[l] == b[(l+j) % n] && a[l] == b[(l+k) % n]) {
++m;
}
}
}
}
}
}
if (m > max) {
max = m;
}
}
return max;
}
int
main(int argc, char ** argv)
{
int n = 5;
int a[] = { 1, 5, 4, 3, 2 };
int b[] = { 1, 3, 2, 4, 5 };
int c[] = { 2, 1, 5, 4, 3 };
std::cout << solve(n, a, b, c) << std::endl;
return 0;
}
Хорошо, я не совсем понимаю: мы выбираем элемент 0 из первого списка: 2. Как он определяет поворот? И где я могу получить значение snd пары? Мне все еще нужно перебирать список snd, чтобы найти индекс этого значения, правильно? – CuriousMan
@ CuriousMan Предположим, мы выбрали 1. Мы знаем его положение во всех трех списках. Вращение второй и третьей - это просто разность позиций по модулю N. Нам не нужно зацикливаться: нам просто нужна обратная перестановка. – kraskevich
Я только что написал это на бумаге для примера N = 5. Он совпадает с 5,3 и 2. Если я рассчитываю индексные кортежи, как вы писали, я получаю (2,4), (2,4) и (2,4). Теперь я вижу картину. Большое спасибо! – CuriousMan