ENG  RUSTimus Online Judge
Online Judge
Задачи
Авторы
Соревнования
О системе
Часто задаваемые вопросы
Новости сайта
Форум
Ссылки
Архив задач
Отправить на проверку
Состояние проверки
Руководство
Регистрация
Исправить данные
Рейтинг авторов
Текущее соревнование
Расписание
Прошедшие соревнования
Правила

1174. Weird Permutations

Ограничение времени: 0.5 секунды
Ограничение памяти: 64 МБ
Three Romanian programmers developed this new algorithm which generates all the N! permutations with N elements in a specific order, they called the transposition order. The algorithm starts with the permutation 1 2 3 .. N. Then it chooses a pair of two adjacent elements (that is, two elements which are located on consecutive positions) and switches them. This way, they get a new permutation. They do the same for this new permutation and they obtain a new one and so on, until all the N! permutations are generated. You realize that the algorithm must be pretty smart in order to generate all the N! permutations exactly once (without repetitions).
Hopefully, your task will not be to write such an algorithm. In fact, you are given the files perm.pas and perm.cpp, which are two implementations of this algorithm (in Pascal and C++). They read the integer N (1 ≤ N ≤ 100) from the keyboard and print to the file perm.txt all the N! permutations, one per line, in the order in which the algorithm generates them.
What you have to do is, given a permutation, to find out its index in the list of permutations generated by the algorithm.
Perm.pas Perm.cpp
const
  fileout = 'perm.txt';
  MAXN = 100;

var
  fout :text;
  n, i :integer;
  permut :array [1..MAXN] of integer;
  position :array [1..MAXN] of integer;
  dir :array [1..MAXN] of integer;

procedure PrintPermutation;
begin
  for i := 1 to n do
    write(fout, ' ', permut[i]);
  writeln(fout);
end;

procedure Switch(p1, p2 :integer);
var
  xch :integer;
begin
  xch := permut[p1];
  permut[p1] := permut[p2];
  permut[p2] := xch;
  position[permut[p1]] := p1;
  position[permut[p2]] := p2;
end;

procedure GeneratePermutation(nn :integer);
var ii :integer;
begin
  if (nn = n + 1) then
    PrintPermutation
  else
  begin
    GeneratePermutation(nn + 1);
    for ii := 1 to nn - 1 do
    begin
      Switch(position[nn],
             position[nn] + dir[nn]);
      GeneratePermutation(nn + 1);
    end;
    dir[nn] := -dir[nn];
  end;
end;

begin
  readln(n);
  for i := 1 to n do
  begin
    permut[i] := i;
    position[i] := i;
    dir[i] := -1;
  end;

  assign(fout, fileout);
  rewrite(fout);

  GeneratePermutation(1);

  close(fout);
end.
#include <stdio.h>

const char *fileout = "perm.txt";
const int MAXN = 100;

FILE *fout;
int n, i;
int permut[MAXN + 1];
int position[MAXN + 1];
int dir[MAXN + 1];

void PrintPermutation()
{
  for (i = 1; i <= n; i++)
    fprintf(fout, " %d", permut[i]);
  fprintf(fout, "\n");
}

void Switch(int p1, int p2)
{
  int xch = permut[p1];
  permut[p1] = permut[p2];
  permut[p2] = xch;
  position[permut[p1]] = p1;
  position[permut[p2]] = p2;
}

void GeneratePermutation(int nn)
{
  int ii;

  if (nn == n + 1)
    PrintPermutation();
  else
  {
    GeneratePermutation(nn + 1);
    for (ii = 1; ii <= nn - 1; ii++)
    {
      Switch(position[nn],
             position[nn] + dir[nn]);
      GeneratePermutation(nn + 1);
    }
    dir[nn] = -dir[nn];
  }
}

int main()
{
  scanf("%d", &n);
  for (i = 1; i <= n; i++)
  {
    permut[i] = i;
    position[i] = i;
    dir[i] = -1;
  }

  fout = fopen(fileout, "wt");

  GeneratePermutation(1);

  fclose(fout);
  return 0;
}

Исходные данные

The first line contains a single integer: N (1 ≤ N ≤ 100). The 2nd line contains N integers separated by blanks. They are the given permutation with N elements.

Результат

Print one single integer, which will be the index of the permutation in the list of N! permutations generated by the algorithm described above.

Пример

исходные данныерезультат
4 
2 3 1 4 
17 

Замечания

Run the 2 given programs for N=4 and you will notice that the permutation 2 3 1 4 will be on the 17th line of the file perm.txt.
Автор задачи: Mugurel Ionut Andreica. The Pascal and C++ programs of the three programmers are improved (and, obviously, modified) versions of two programs written by Frank Ruskey (I found them on the Web). So, thanks Frank!
Источник задачи: Romanian Open Contest, December 2001