Модераторы: Daevaorn
  

Поиск:

Закрытая темаСоздание новой темы Создание опроса
> Двоичная куча, задача про колкола 
:(
    Опции темы
Dev1L
Дата 15.1.2008, 15:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 13.1.2008

Репутация: нет
Всего: нет



Вот такая задачка:

Как известно, очереди с приоритетами часто используются для моделирования последовательности событий, которые должны происходить в разные моменты времени. Реализуйте очередь с приоритетами на основе пирамиды (двоичной кучи) и на её основе решите следующую задачу. 
Дано N колоколов, которые управляются некоторым механизмом. Колокол с номером i в первый раз ударит в момент ti и затем будет ударять через каждые ti секунд. Требуется определить, какой из колоколов ударит K-м по счету (или какие колокола, если ударят несколько одновременно). 
Ограничения: N до 1000, K до 1000000. Указание к решению. Каждый элемент очереди будет содержать два поля – приоритет и номер колокола (поэтому удобно создать соответствующий тип данных с помощью struct). В роли приоритета будет выступать время, когда следует нанести очередной удар.

Код

#include<stdio.h>
#include<stdlib.h>

typedef struct {
    int value;
    int  key;
} ITEM;

class HEAP {           //   создаем класс heap (двоичная куча)
public:
    ITEM *h;
    int  size;

    HEAP(unsigned int n) {
       size = 0;
       h = (ITEM*) malloc( sizeof(ITEM) * n);  //выделение памяти
    }

    ~HEAP() {
        if(h) free(h);   // освобождение блока памяти
    }

    int add(ITEM x) {   //  добавляем новый элемент в конец кучи
       h[++size]=x;     //размер кучи +1 , т.к
                        // число шагов всплытия меньше чем высота дерева
       checkup(size);   // смотрим на родителя и проверяем свойство кучи
       return 1;
    }

    int extract_min(ITEM *x) {   // извлечение минимального элемента
      if(size ==0) return 0;     // если размер кучи равен 0 выход
      *x = h[1];                // отложим вершину кучи в сторону,
                                //чтобы в конце вернуть ее в качестве результата
      h[1] = h[size--];         // самый последний элемент в вершину кучи
      checkdown(1);             // "топим" его
      return 1;
    }
private:
    void checkup(int c) {          //    проверка сверху
        int p;                     // p-ключ родителя с-ключ ребенка
        p = c / 2;
        if( p == 0 )return;
                                   // сравниваем ключ ребенка с ключем родителя
        if(h[p].key > h[c].key) {  // если ключ родителя больше ключа ребенка
           ITEM tmp;
           tmp = h[p]; h[p] = h[c]; h[c] = tmp; //меняем их местами
           checkup(p);              // проверка сверху для нового родителя
        }
    }
    
    void checkdown(int p) {         //  проверка снизу
        int c;                      // p-ключ родителя с-ключ ребенка
        c = 2*p;
        if( c > size ) return;

        if( c+1 <= size && h[c + 1].key < h[c].key ) c++;
        if( h[c].key < h[p].key ) { // если ключ ребенка меньше ключа родителя
          ITEM tmp;
          tmp =  h[c]; h[c] = h[p]; h[p] = tmp; //меняем их местами
          checkdown(c);   // проверка снизу для нового ребенка
       }
    }
};

int main() {
    HEAP heap(1000);
    int n, i, k, j, z;
    ITEM x;

    scanf("%d", &n);                 // ввод количества колоколов
    scanf("%d", &k);                 // счет

    for(i = 0; i < n; i++){          // ввод элементов с приоритетами

       scanf("%d", &x.value);        // номер колокола
       scanf("%d", &x.key);          // его время
       heap.add(x);                  // добавляем элемент
    }
    for(i = 0; i < k; i++){
    while( heap.extract_min(&x) ) {  // извлекаем минимальный элемент
       j=x.value;                    // смотрим номер этого колокола
       x.value=x.value+x.key;        // прибавляем к приоритету этого элемента
       }                             // временной промежуток того колокола
    }
     printf("%d ", j);               // выводим результат
    return 0;
}


неправильно считает
PM MAIL   Вверх
MAKCim
Дата 16.1.2008, 11:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Dev1L, 

 ! 
MAKCim
Модератор: Дубликат!




--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
  
Закрытая темаСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0450 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.