3. Перестановки

Не решаласьСредняя

Есть два метода генерации случайных перестановок длины 8 — правильный и творческий. Код этих методов приведён ниже.

Реализация на C++:

vector<int> RandomPermutation() {
    vector<int> perm;
    for (int i = 0; i < 8; ++i) {
        perm.push_back(i);
    }
    std::random_device rd;
    std::mt19937 g(rd());
    shuffle(perm.begin(), perm.end(), g);
    return perm;
}

vector<int> StupidPermutation() {
    const vector<int> partialSums = {0,1,8,35,111,285,
        628,1230,2191,3606,5546,8039,11056,14506,18242,
        22078,25814,29264,32281,34774,36714,38129,39090,
        39692,40035,40209,40285,40312,40319,40320};
    int r = rand() % (partialSums.back() + 1);
    int numInv = 0;
    while (partialSums[numInv] < r) {
        numInv++;
    }
    vector<int> perm;
    for (int i = 0; i < 8; ++i) {
        perm.push_back(i);
    }
    for (int step = 0; step < numInv; ++step) {
        int t1 = rand() % 8;
        int t2 = rand() % 8;
        swap(perm[t1], perm[t2]);
    }
    return perm;
}

Реализация на Python:

def RandomPermutation():
    perm = list(range(8))
    random.shuffle(perm)
    return perm

def StupidPermutation():
    partialSums = [0,1,8,35,111,285,
        628,1230,2191,3606,5546,8039,11056,14506,18242,  
        22078,25814,29264,32281,34774,36714,38129,39090,  
        39692,40035,40209,40285,40312,40319,40320]
    r = random.randint(0, partialSums[-1])
    numInv = 0
    while partialSums[numInv] < r:
        numInv += 1
    perm = list(range(8))
    for step in range(numInv):
        t1 = random.randint(0, 7)
        t2 = random.randint(0, 7)
        perm[t1], perm[t2] = perm[t2], perm[t1]
    return perm

В правильном методе генерируется случайная перестановка. В творческом сначала выбирается число numInvnumInv, соответствующее доле неправильно упорядоченных пар чисел в случайной перестановке. Массив partialSumspartialSums выбран таким образом, что распределение величины numInvnumInv получается правильным.

Дальше допущена ошибка, в результате которой не все перестановки будут получаться с одинаковыми вероятностями. Получив достаточно большое количество перестановок, сгенерированных одним из методов, можно угадать, что это был за метод.

В этой задаче по набору из 10001000 перестановок необходимо определить, каким методом он был получен. Дано nn таких наборов, нужно отсортировать их так, чтобы сначала шли хорошие наборы, а потом творческие.

Решение засчитывается, если среди всех пар наборов (хороший, творческий), хотя бы 98% идёт в правильном порядке (детали в примечании).

Формат ввода

Файл permutations.in находится в архиве, доступном по адресу.

В первой его строке указано одно число nn — количество наборов перестановок. В каждой из следующих 1000n1000 n строк указано по перестанове чисел от 00 до 77. Первая 10001000 строк соответствет первому набору перестановок, вторая 10001000 второму и т.д.

Формат вывода

Выведите nn чисел — в ii-ой строке должен быть указан номер набора перестановок (от 00 до n1n - 1). Сначала должны идти номера хороших наборов, потом творческих.

Примечание

Для определения корректности ответа вычисляются две величины:

  • totaltotal: количество пар индексов i<ji < j таких, что генераторы для наборов ii и jj различны;
  • goodgood: количество пар индексов i<ji < j таких, что генератор для набора ii "хороший", а для jj "творческий".

Ответ считается корректным, если goodtotal0.98\frac{good}{total} \ge 0.98.

Ограничения

Ограничение времени

1 с

Ограничение памяти

64 МБ

Теги

Без компиляции
Нужно войти, чтобы отправить решение.Войти