Помощь - Поиск - Пользователи - Календарь
Полная версия: Перестановки > Информатика / Программирование
Образовательный студенческий форум > Другие дисциплины > Информатика / Программирование
Tri
Есть вот такая задача:
Цитата
Напишите программу для определения при разных значениях n числа перестановок PI=(pi 1,pi 2,…,pi n) на множестве {1,2,…n}, которые обладают тем свойством, что из pi i- i = pi j-j (mod n) следует i=j.

Я не совсем понимаю как реализовать условие, и что должно получиться.
Подскажите, пожалуйста, решение.
Вот такие наработки:
Код

{ программа генерации перестановок N элементного
  множества в лексикографическом порядке }

Program perms;
var
  i, j, h, n, k, x, y: integer;
  a:array[0 .. 100] of integer;  { массив для хранения перестановки }

{процедура вывода полученной перестановки}
procedure output;
var i: integer;
begin
  writeln;
  for i:=1 to n do write(a[i],' ');
end;

begin
  write('количество элементов перестановки: '); readln(n);
  fillchar(a, sizeof(a), 0);

  { ввод элементов начальной перестановки }
  for i:=1 to n do a[i]:=i;
  i:=n;
  j:=i;
  repeat

//здесь пытаюсь проверить условие (не уверена, что оно вообще здесь должно быть)

  
    x:= a[i]-i;
    y:=a[j]-j mod n;
    if (x=y) and (i=j) then

    output;  { вывод текущей перестановки }
    i:=n;
    while a[i-1]>a[i] do dec(i); { поиск скачка }
    j:=i-1;
    h:=a[j];
    while a[i+1]>h do inc(i); { поиск первого меньшего элемента }
    a[j]:=a[i];  a[i]:=h;
    i:=j+1; k:=n;
    while i<k do begin { перестановка ”хвоста” }
       h:=a[i]; a[i]:=a[k]; a[k]:=h;
       inc(i); dec(k)              
    end
  until j=0;
end.

Заранее большое спасибо!
creer
Хм, я тоже не очень понял условие, особенно необходимое свойство. Условие точно записано в таком виде без всяких дополнительных скобочек или индексов?
Tri
Вот исходник задания)
creer
Перевожу на русский язык smile.gif.
У нас есть куча объектов какого-то класса pi, а именно числа. Чисел у нас ровно n, причем начинаются они с единицы. И мы хотим эти числа перемешать. Но кто-то захотел, чтобы при перемешивании (всеми способами) мы кое-что посчитали, а именно, сколько же всего возможно комбинаций при данном числе объектов, когда все значения выражения "текущее положение числа минус само число" будут различны, причем по модулю n.
У кого есть возражения? smile.gif
Tri
Честно говоря, не очень поняла:)
Значения выражения должны быть, наверное, одинаковыми, раз знак равенства? И не совсем понимаю как это запрограммировать, сравнение загнать в цикл, в котором менять i и j?
creer
Запрограммировать можно все что угодно wink.gif
Главное понять смысл smile.gif
Чтобы pi[i] - i = pi[j] - j (mod n) выполнялось только при i = j, и не выполнялось при i <> j, нужно чтобы pi[i] - i для всех i=1..n было различно, ну это как я понял smile.gif.
Возможно я не прав, поэтому мне интересно послушать другие идеи.
P.S.
Задачку сдать нужно завтра? wink.gif
Tri
Спасибо большое за идею, попробую.
p.s.Нет, сдавать, к счастью, не завтра:)
creer
Попробуйте wink.gif
Если будет время, то завтра напишу свой вариантик smile.gif
creer
Я добавил одну функцию в программу, которая для каждой позиции проверяет то, что я описывал выше. Посмотрите smile.gif

Код
{ программа генерации перестановок N элементного
  множества в лексикографическом порядке }

Program perms;
var
  i, j, h, n, k, count: integer;
  a:array[0 .. 100] of integer;  { массив для хранения перестановки }

{процедура вывода полученной перестановки}
procedure output;
var i: integer;
begin
  writeln;
  for i:=1 to n do write(a[i],' ');
end;

function testposition:boolean;
var
  ta:array [0..100] of boolean;
  i: integer;
begin
  fillchar(ta, sizeof(ta), false);
  for i:=1 to n do
  begin
    if (ta[(a[i] - i + n) mod n] = false) then
      ta[(a[i] - i + n) mod n]:=true
    else
    begin
      Result:=false;
      Exit;
    end;
  Result:=true;
  end;

end;

begin
  write('количество элементов перестановки: ');
  readln(n);
  fillchar(a, sizeof(a), 0);
  count:=0;

  { ввод элементов начальной перестановки }
  for i:=1 to n do a[i]:=i;
  i:=n;
  j:=i;
  repeat

    //output;  { вывод текущей перестановки }
    if testposition then
      inc(count);
    i:=n;
    while a[i-1]>a[i] do dec(i); { поиск скачка }
    j:=i-1;
    h:=a[j];
    while a[i+1]>h do inc(i); { поиск первого меньшего элемента }
    a[j]:=a[i];  a[i]:=h;
    i:=j+1; k:=n;
    while i<k do begin { перестановка "хвоста" }
       h:=a[i]; a[i]:=a[k]; a[k]:=h;
       inc(i); dec(k)
    end
  until j=0;
  writeln(count);
  readln;
end.
malk
Код

procedure TForm1.Button1Click(Sender: TObject);
var s,n:integer;
type  sm=set of 0..99;

procedure rek(b,c:sm; i:integer);
var x:integer;
begin
   for x:=0 to n-1 do
      if (x in b)and(((x-i+n)mod n)in c) then
         begin
            if i<n-1 then rek(b-[x],c-[(x-i+n)mod n],i+1) else s:=s+1;
         end;
end;

begin
   s:=0;
   n:=strtoint(edit1.Text);
   rek([0..n-1],[0..n-1],0);
   label2.Caption:=inttostr(s);
end;

Для четных n искомое будет всегда равно 0.
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.
Русская версия Invision Power Board © 2001-2025 Invision Power Services, Inc.