очередь с двумя концами (ЗаЗа)
От: ilya123 Россия  
Дата: 13.01.03 20:08
Оценка:
Имеется двунаправленная очередь (можно взять элемент слева, поместить элемент слева, взять элемент справа, поместить элемент справа). В очереди лежат какие-то элементы — не обязательно числа.
Нужно определить, сколько элементов содержит очередь.

Очередь не должна измениться в процессе подсчета. Можно использовать лишь малое количество памяти.

28.01.03 20:59: Ветка выделена из темы Занимательные задачки
Автор: fAX
Дата: 07.08.02
— ХД
Re[2]: очередь с двумя концами (ЗаЗа)
От: fAX Израиль  
Дата: 14.01.03 00:16
Оценка:
Здравствуйте, ilya123, Вы писали:

I>Имеется двунаправленная очередь (можно взять элемент слева, поместить элемент слева, взять элемент справа, поместить элемент справа). В очереди лежат какие-то элементы — не обязательно числа.

I>Нужно определить, сколько элементов содержит очередь.

I>Очередь не должна измениться в процессе подсчета. Можно использовать лишь малое количество памяти.

Элементы уникальны? Что есть "малое количество памяти" константа?
Если элементы уникальны — достаточно памяти под один элемент. Запоминаем элемент например, слева.
Перемещаем его вправо. И так до тех пор, пока не придём к начальному элементу. Естественно, считаем количество перестановок.

            --------------------------------- 
очередь  /-- *QWERTYUIOP{ASDFGHJKL:"ASDFGHJK  <--\
         |  ---------------------------------     |
          \_______________________________________/


Другой вопрос, если элементы неуникальны. Тогда задача не имеет решения (ИМХО), т.к. невозможно различить:

    ------------------------
     *QWERTYUIOP*QWERTYUIOP
    ------------------------
и

    --------------
     *QWERTYUIOP*
    --------------
т.е. циклическую последовательность.
...Complex problems have simple, easy-to-understand wrong answers...
(Grossman's Misquote of H.L.Mencken)
Re[3]: очередь с двумя концами (ЗаЗа)
От: fAX Израиль  
Дата: 14.01.03 00:20
Оценка:
Здравствуйте, fAX, Вы писали:

I>>Очередь не должна измениться в процессе подсчета. Можно использовать лишь малое количество памяти.

Очередь не должна измениться в процессе подсчета = не должна измениться после подсчёта или не должна изменяться во время подсчёта?
...Complex problems have simple, easy-to-understand wrong answers...
(Grossman's Misquote of H.L.Mencken)
Re[2]: очередь с двумя концами (ЗаЗа)
От: Atilla Россия  
Дата: 14.01.03 08:11
Оценка: 27 (2)
Здравствуйте, ilya123, Вы писали:

I>Имеется двунаправленная очередь (можно взять элемент слева, поместить элемент слева, взять элемент справа, поместить элемент справа). В очереди лежат какие-то элементы — не обязательно числа.


пусть это не числа (любое множество с числом элементов >=1 и с операциями сравнения). Но для простоты будем считать, что там — целые числа, также будем считать, что число элементов в очереди конечно.

Пусть крайне-правый элемент равен 1, заменим его на 2 и будем циклически прокручивать его влево до тех пор, пока оттуда не вылезет 2, считаем число сдвигов N. Затем всю систему циклически прокручиваем вправо, меняем 2 на 1 (т.е. возвращаем очередь в исходное состояние), прокручиваем всю очередь опять влево на N, если в левом конце очереди вылезет 1, то ответ мы нашли, он равен N, затем восстанавливаем очередь, прокручивая ее вправо на N. Если вылезала двойка, значит размер не найден, опять заменяем 1 на 2, крутим все влево до тех пор, пока не появится 2 (но >N раз) и так далее.

Теперь то же самое, но в коде:

value roll_left(queue& q, int n=1)
{
    value r;
    for(int i=0;i<n;i++)
    {
        r=q.pop_left();
        q.push_right(r);
    }
    return r;
}
value roll_right(queue& q, int n=1)
{
    value r;
    for(int i=0;i<n;i++)
    {
        r=q.pop_right();
        q.push_left(r);
    }
    return r;
}

int size(queue q)
{
    int N=0;
    while(1)
    {
        value l=q.pop_right();
        q.push_right(l+1);
        int M=0;
        do
        {
            M++;
            r=roll_left(q);
        }while(r!=l+1 && M<=N);
        roll_right(q, M);
        q.pop_right();
        q.push_right(l);
        value r=roll_left(q, M);
        roll_right(q, M);
        if(r==l)
            return M;
        N=M;
    }
}


абсолютную правильность кода не гарантирую, оптимальность — тем более
... << RSDN@Home 1.0 beta 4 >>
Кр-ть — с.т.
Re[3]: очередь с двумя концами (ЗаЗа)
От: fAX Израиль  
Дата: 15.01.03 23:32
Оценка:
Здравствуйте, Atilla, Вы писали:

A>Здравствуйте, ilya123, Вы писали:


I>>Имеется двунаправленная очередь (можно взять элемент слева, поместить элемент слева, взять элемент справа, поместить элемент справа). В очереди лежат какие-то элементы — не обязательно числа.


A>пусть это не числа (любое множество с числом элементов >=1 и с операциями сравнения). Но для простоты будем считать, что там — целые числа, также будем считать, что число элементов в очереди конечно.


A>Пусть крайне-правый элемент равен 1, заменим его на 2 и будем циклически прокручивать его влево до тех пор, пока оттуда не вылезет 2, считаем число сдвигов N. Затем всю систему циклически прокручиваем вправо, меняем 2 на 1 (т.е. возвращаем очередь в исходное состояние), прокручиваем всю очередь опять влево на N, если в левом конце очереди вылезет 1, то ответ мы нашли, он равен N, затем восстанавливаем очередь, прокручивая ее вправо на N. Если вылезала двойка, значит размер не найден, опять заменяем 1 на 2, крутим все влево до тех пор, пока не появится 2 (но >N раз) и так далее.


А как насчёт

111121111 ?
...Complex problems have simple, easy-to-understand wrong answers...
(Grossman's Misquote of H.L.Mencken)
Re[4]: очередь с двумя концами (ЗаЗа)
От: Atilla Россия  
Дата: 16.01.03 06:17
Оценка:
Здравствуйте, fAX, Вы писали:

fAX>111121111 ?


точно так же:

1. 111121111 -> 111121112 — заменили элемент
2. -> 111211112 — прокрутили на N=5
3. -> 111121111 — вернули назад
4. -> 111111112 — прокрутили еще раз на N=5, опять вылезла двойка
5. -> 111121111 — вернули
6. -> 111121112 — опять заменили элемент
7. -> 111121112 — прокрутили на N=9>5
8. -> 111121111 — вернули назад
9. -> 111121111 — еще раз прокрутили на N=9, вылезла единица => return 9
... << RSDN@Home 1.0 beta 4 >>
Кр-ть — с.т.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.