Подразделы

Другие разделы

Дата и время

16/11/2024 17:13:22

Авторизация

Имя:
Пароль:
Зарегистрироваться
Восстановить пароль
 

print8. Новое слово в рекламе

Сложная задача на работу со строками.
Будем перебирать все возможные `K` от 1 до `|s|`, пока набор из `K` блоков, содержащих заданное слово `s`, не будет найден.
Назовем `K`-подсловом `w_j`, где `j` от 1 до `K`, последовательность букв из `s` вида `s_j\ s_{K+j}\ s_{2K+j}\ …`.
Для каждого `K` заполняем массив `T`[1..`L`, 1..`K`] следующим образом. Вначале массив инициализируется нулями. Затем устанавливаем `T`[`i,j`]=`m`, если `K`-подслово `w_j` начинается с позиции `i` в блоке `B_m`. Заполнения массива `T` выполняется за время `O(K*N*L*|s|/K)=O(|s|*N*L)`.
var s:string;
    b:array[1..100] of string; { блоки }
    T:array[1..100,1..200] of integer;
    n,L,i,j,k,m,p,q,wlen,slen:integer;
    flg:boolean;
...
slen:=length(s);
for k:=1 to length(s) do
begin
  { заполнение таблицы T }
  for i:=1 to L do
    for j:=1 to k do
      T[i,j]:=0;
  for j:=1 to k do
  begin
    wlen:=(slen-j+k) div k; { длина j-го K-подслова }
    for i:=1 to L-wlen+1 do
      for m:=1 to n do
      begin
        { проверяем, что j-е K-подслово начинается с позиции i в блоке m }
        p:=j;
        q:=i;
        while (p<=slen) and (b[m][q]=s[p]) do
        begin
          inc(q);
          p:=p+k;
        end;
        if p>slen then
        begin
          T[i,j]:=m;
          break;
        end;
      end;
  end;
  ...
end;
writeln(-1);
После этого мы должны найти в этом массиве последовательность из `K` ненулевых ячеек, начиная с некоторой ячейки `(i,j)`: `T`[`i,j`] `T`[`i,j+1`] … `T`[`i,K`] `T`[`i-1,1`] … `T`[`i-1,j-1`]. Номера блоков в этих ячейках образуют требуемый набор блоков. Поиск последовательности из `K` ненулевых ячеек в массиве `T` можно выполнить за время `O(L*K)`, если при обнаружении нулевой ячейки сдвигаться на `K` позиций от нее.
  i:=1;
  j:=1;
  while i<=L do
  begin
    flg:=true;
    for p:=j to k do
      if T[i,p]=0 then
      begin
        flg:=false;
        i:=i+1;
        j:=p;
        break;
      end;
    if flg then
    for p:=1 to j-1 do
      if T[i-1,p]=0 then
      begin
        flg:=false;
        j:=p;
        break;
      end;
    if flg then
    begin
      { вывод ответа }
      writeln(k);
      for p:=j to k do
        write(' ',T[i,p]);
      for p:=1 to j-1 do
        write(' ',T[i-1,p]);
      writeln;
      halt(0);
    end;
  end;
Общее время работы алгоритма равно `O(|s|*(|s|*N*L+K*L))=O(|s|^2*N*L)`.
loading