Сайт підготовки до олімпіади з інформатики

програмування в С++

Школа олімпійського резерву з інформатики
Задачі масиви 07_10_2011 PDF Печать E-mail
Добавил(а) Administrator   
14.10.11 11:57

1. Масиви

1. Дано масив A[1..15]. Скласти програму заміни всіх його  елементів, що більші 10 на нулі.

2. Дано лінійну таблицю  із  n  дійсних  чисел.  Знайти  суму  S  всіх додатних елементів.

3. В таблиці а[1..100)]всі елементи рівні 2,3,4 або 5. Написати  програму, яка заміняє 2 на 5, 3 на 4, 4 на 3, 5 на 2.

4. Скласти програму підрахунку суми елементів з непарними номерами  масиву A[1..25].

5. Дано  масив  A[1..2N].  Скласти  програму   знаходження   різниці   сум елементів першої та другої половини масиву.

6.  Дано  лінійну  таблицю  із  n  дійсних  чисел.  Замінити  від'ємні елементи їх квадратами.

7. Задано таблиця A[1..N]. Побудувати таблицю  B[1..N],  в  якій  першими розміщені всі від'ємні елементи таблиці A, а потім всі додатні.

8. Із елементів масиву (a1,a2,...,a20) складіть масив B, елементи якого по модулю більші деякого значення С(|a|>c).

9. Дано натуральна таблиця A[1..10]. В таблицю М записати тільки ті числа, остача від ділення яких на 3 рівна 1, а на 5 рівна 2.

10. Провірити, чи є в одномірному числовому масиві  хоча  б  одна  пара сусідніх чисел, які ї протилежними.

11. Заданий одномірний числовий масив. Визначити суму добутків  всіх  пар  сусідніх чисел.

12. Визначити в одномірному числовому масиві число сусідства із двох чисел різного знаку.

13. Для заданого масиву A(N) знайти  суму  всіх  елементів,  не  більших заданого числа N.

14. Дано масив A[1..M]. Скласти програму перестановки місцями елементів з  парними та непарними номерами.

15. Визначити в одномірному числовому масиві суми додатних і  від'ємних елементів.

16. Провірити, чи ї в даному одномірному числовому масиві хоча  б  одна пара чисел, які співпадають по величині.

17. Скласти програму запису в таблицю квадратів чисел від 1 до 100.

18. Даний одномірний  числовий  масив.  Визначити  суму  добутків  всіх трійок сусідніх чисел.

19. Скласти  програму  підрахунку  кількості  мінімальних  елементів  в масиві A[1..N].

20.В одномірному числовому масиві всі від'ємні елементи замініть  нуля ми.

21. Провірити, чи є одномірний числовий масив упорядкованим по зростанню.

22.  Дано  натуральний  масив  A[1..N].Скласти  програму  підрахунку  парних елементів цього масиву.

23. Дано лінійний масив A[1..M].Скласти програму заміни елементів з  непарними номерами на їх квадрати.

24. Скласти програму заміни в прямокутному масиві A[1..k] всіх елементів, що більші від 10 на нулі.

25. Дано нат таб A[1..20]. В таблицю М записати тільки ті числа, остача від ділення яких на 3 рівна 1.

26.  Визначити  в  одномірному  числовому  масиві  число   сусідств   з взаємо-обернених чисел.

27. Заданий одномірний числовий масив. Визначити суму добутків  всіх  пар сусідніх чисел.

29. Даний одномірний  числовий  масив.  Визначити  суму  всіх чисел.

2.Масиви (Серйозні розважалки)

1. Барон Мюнхаузен, вийшовши на екологічно чисте по­лювання, зарядив свою рушницю кісточками вишень. Після того як він вдало влучив поміж роги оленям, в яких влучило відповідно k1,k2,...,kN кісточок, у них на головах виросли чудові молоді вишеньки. Скільки нових саджанців зміг подарувати барон Мюнхаузен садівникам-дослідникам?

2. Мама розвела оранжерею кактусів, деякі з яких були колючі, а інші - ні. Маленька донечка Яринка вирішила, що голки на кактусах - це надто зухвало, і тому старанно поголила їх бритвою. Добре, що у мами залишився записник, в якому всі кактуси були позначені кількістю голочок α12,..., αN (голі кактуси були позначені 0). Скількох кактусів не торкнулася рука юної перукарки?

3. Середню групу дитячого садочка вивели на прогулянку. Скільки дівчаток і скільки хлопчиків видно з-за паркану, якщо зріст хлопчиків задається у сантиметрах від'ємними числами, а дівчаток - додатними у вигляді цілих значень α12,..., αN ? Окрім того, у всіх дівчаток на голівках зав'язані бантики заввишки 10 см, а висота паркану H см.

4. Маленький онучок вирішив допомогти бабусі підстригти квіти у її дорогоцінному квітнику, зрізавши лише бутони та квіточки на них. На щастя, кмітливий хлопчик зрізав лише ті квіти, які були заввишки від h1 см до h2, см від землі. Скільком квіточкам пощастило бути підстриженими, якщо висота їх у сантиметрах становить α12,..., αN ?

5. Коли барон Мюнхаузен вирішив пообідати, він прив'язав до довгої мотузки шматок сала і закинув його у повітря. Зграя диких гусей, що пролітала тим часом над помешканням барона, заціка­вилася незвичним предметом і найстарший гусак, що очолював зграю, проковтнув його. Не встиг він насолодитися відчуттям ситості, як шматок сала проскочив через нього і зник у дзьобі другого гусака і т.д. Тепер доля обіду барона Мюнхаузена залежала лише від довжини мотузки! Скільки кілограмів підсмаженої гусятини було подано на обід барона Мюнхаузена, якщо довжина мотузки становила L см, N гусей летіли на відстані h см один від одного, довжина кожного з них дорівнює k см, а вага цих гусей у кілограмах становила m1,m2,...,mN ?

6. Маленький Дмитрик щомісяця виростає на 2 cм, а у бабусі в комірчині облаштовано полички з різними ласощами - варенням, джемом, повидлом. Акуратистка бабуся записувала висоту і наступний порядковий номер у свій записник кожної нової полички в тій послідовності, як вона з'являлася у комірчині завдяки дідусеві. Висота цих поличок була а1, а2, ... аN, см. Нові полички дідусь прибивав, де йому заманеться - вище, нижче і між тими, що вже були. З'ясувати, через скільки місяців до яких поличок, враховуючи їх порядок запису в бабусиній книжці, добереться Дмитрик (наприклад, спочатку до п'ятої, занотованої у записнику, потім до другої і т.д.), якщо він відкрив для себе бабусину комірчину, коли його зріст був Н1 см, а доросте Дмитрик до H2 см.

7. Велосипедист-початківець Павлуша виїхав на широку дорогу. Але їхати інакше, ніж за законом синусоїди, йому ніяк не вдавалося. Юний спортсмен стартував у точці Х0 на осі ОХ, а центри основ стовпів знаходяться у точках х1,х2,...,хn на цій же осі, яку перетинає синусоїда руху велосипедиста. Скільки стовпів трапляться на шляху Павлуші, якщо шириною стовпа можна знехтувати?

8. Завзятий водій Василь Іванович вирішив поставити рекорд пе­регонів між містом Мляшем та містом Пляшем. Спочатку він придбав карти розташування заправок пальним на шляху між Мляшем та Пляшем, де відстань між заправками була позначена числами а1,а2,...,аN а потім побився об заклад зі своїми друзями, що вста­новить рекорд за Т год. Одна проблема турбувала Василя Івановича: об'єм бака для пального складав К л, а запасної каністри у нього не було. Витрати пального в дорозі становили 1л на 10 км шляху. Для еко­номії часу Василь Іванович на кожній заправці визначав, чи варто вит­рачати 10 хв. на дозаправку, чи можна доїхати до наступної заправки на залишках пального у баці. Чи зможе Василь Іванович встановити рекорд, якщо перша заправка знаходиться у місті Мляші, остання - у місті Пляші, а сам Василь Іванович їде зі сталою швидкістю ν км/год? Чи може таке статися, що Василь Іванович взагалі не доїде до міста Пляша?

9. Лікар-психіатр призначив Сергійкові лікування від лайливих слів. Виконуючи поради психіатра, хворий повинен був записувати у таблицю по днях упродовж місяця кількість використаних ввічливих слів «Дякую», «Пробачте», «Прошу». У який день місяця друзям Сергійка повезло на ввічливі слова найбільше? Якого дня місяця у хлопчика був найгірший настрій? Які ввічливі слова Сергійкові найбільше до вподоби?

 
Задача 3. Task3 PDF Печать E-mail
Добавил(а) Гісь Ігор Володимирович   
03.10.12 09:23

Задача 3. Task3

Для заданого натурального N(N<=100) знайти всі значення виразу a o b о c, де a, b, c натуральні числа <=N операцією o(+ - *).

Вхідний файл Task3.in містить рядок з одного натурального числа.

Вихідний файл Task3.out містить рядок з послідовність чисел через пропуск в зростаючому порядку.

 
Теорія графів Турнір «Графи» PDF Печать E-mail
Добавил(а) Гісь Ігор Володимирович   
23.10.13 10:52

Теорія графів

Турнір «Графи»

1

Пошук в глибину

void p(int k, int v)

{c[k]=v;

if (v==v2 || k>=n) {

if (v==v2)

{

//for (int i=1;i<=k;i++)cout<<c[i]<<" ";cout<<endl;

int s=0;

for (int i=1;i<k;i++)s=s+a[c[i]][c[i+1]];

//cout<<"s="<<s<<endl;

if (s<m) m=s;

}

}

else

for (int i=1;i<=n;i++)

if (a[v][i]>0) p(k+1,i);

}

2

Флойда

k= 1;

     for(i= 1;i<=n;i++)x[i]=a[v1][i];

//     {инвариант: x[i] = МинСт(1,i,k)}

                while (k!=n)

                {

                               for(s=1;s<=n;s++){

                                               y[s]=x[s];

                               for(i=1;i<=n;i++) if (y[s]>x[i]+a[i][s]) y[s]= x[i]+a[i][s];

// {y[s] = МинСт(1,s,k+1)}

     for (i=1;i<=n;i++) x[s]=y[s];

                               }

     k++;

                }

3

Форда

for (int k=1; k<=n; k++)

                for (int i=1; i<=n; i++)

                               for (int j=1; j<=n; j++)

                                               a[i][j] = min (a[i][j], a[i][k] + a[k][j]);

4

Прима

 

5

Дейкстри

Алгоритм дуже простий, його реалізація представлена нижче. Алгоритм працює з вершинами як з числами. Тобто кожній вершині зіставляється число - номер представлення в масиві. Величина p - це кількість вершин. Сам алгоритм по вхідній матриці довжин дуг і заданим точкам початку і кінця шляху зберігає його в масив H. Цей масив є співвіднесеними вершинами за наступним правилом: якщо вершина v лежить на потрібному нам найкоротшому шляху, то попередня нею точка на цьому шляху записана як H[v]. Також при цьому ж умові інший масив T в значенні T[v] міститиме довжину найкоротшого шляху від точки початку до v. Також цей алгоритм оперує наступними змінними:

C - матриця довжин дуг. Її розмір C[p, p]. C[v1, v2] - містить довжину дуги від точки v1 до точки v2. Примітка: За відсутності зв'язок між цими точками відстані між ними мають бути нескінченні, а не дорівнюють нулю. Це питання розглядалося раніше.

s - початкова точка шляху в графі. Та, звідки треба знайти шлях в точку t.

t - кінцева точка шляху в графі. Це мета пошуку.

X - цей одновимірний масив служить сховищем міток, для вершин, в яких би ми вже проходили в алгоритмі.

v - поточна вершина обходу (украй динамічна змінна)

////ініціалізація і опис початкового стану змінних

Перебір значень u від 1 до p:

{

                                               T[u] = ∞;

                                               X[u] = 0;

}

                        //                      // триває опис НУ, окремий випадок - початкова вершина.

H[s] = 0;         // немає попередній початковій вершині

T[s] = 0;         // довжина шляху до неї дорівнює нулю

X[s] = 1;         // і ми тут були

v = s;               // встановлюємо початкову вершину, як поточну оброблювану.

Мітка M :       // мітка для стрибків в коді

// // далі перебираємо усі прилеглі до поточної вершини точки, і визначаємо для них

// // мінімальна відстань, порівнюючи записане в масив T і шлях по

// // поточній вершині.

Перебір значень u від 1 до p:

{

                                               якщо X[u]=0 і T[u] > T[v]+C[v, u] те:

{

                                               T[u] =             T[v] + C[v, u];

                                               H[u] = v;        //обов'язково запишемо попередню вершину для цього шляху

}

}

// // далі шукаємо наступну точку для обходу, грунтуючись на її відстані від

// // почала. Для наступного циклу виберемо точки, що мають найменшою шлях,

// // і цей шлях вибирається, грунтуючись на даних масиву T, де довжина

// // шляхи враховує тільки довжину зв'язків, по яких вони йдуть. Т. о.

// // перший знайдений шлях від s до t і буде найкоротшим.

l = ∞;

v = 0;

Для змінної u значення від 1 до p:

{

                                               якщо X[u] = 0 і T[u] < l те:

                                               {

                                                                                              v = u;

                                                                                              l = T[u];

}

}

Якщо v = 0 те:

{

                                               exit(); //немає шляху

} інакше

Якщо v = t те:

{

                                               exit(); //шлях знайдений, наступна вершина і кінцева

} інакше

{

                                               X[v] = 1;

                                               Перейти на мітку M;           // новий круг

}

Якщо залишилися якісь порожні місця, рекомендую пройтися по алгоритму наново, і усвідомити його остаточно. Крок основного циклу виконує дві дії: по-перше, розставляє/оновлює знання про мінімальні шляхи сусідніх з поточною вершин, по-друге, визначає вершину для наступного кроку, яка має найкоротший шлях від початку.

Як бачите, алгоритм не зайде в пошуку далі, ніж треба, і за умови, що вершини лежать близько один до одного, результат буде отриманий дуже скоро. Проте якщо шлях "далекий", то доведеться обійти практично увесь граф. Представлений алгоритм - один з найвідоміших, простіших і дієвіших. Його також називають хвилевим алгоритмом, оскільки обхід здійснюється як би хвилями, оновлюючи прилеглі вершини.

За допомогою алгоритму Дейкстры добре шукати конкретні одноразові шляхи. Але найчастіше на ігровому полі це завдання відбувається багаторазово. Причому з різними початковими умовами. Використовувати цей же алгоритм ніхто не забороняє, але далі я пропоную вашій увазі ще один алгоритм для пошуку найкоротшого шляху. Алгоритм Флойда має схожі початкові дані, але на виході повертає двовимірний аналог масиву H[p] -> H[p][p].

 
26_12_2012 Рекурсія. Бінарні дерева PDF Печать E-mail
Добавил(а) Гісь Ігор Володимирович   
26.12.12 10:13

Дерево (рекурсивне опрацювання дерев)

Те, що зображено на малюнку, називається деревом вибору усіх можливих варіантів двійкових комбінацій, що починаються на 1.

Кожен рівень цього дерева - це рівень розгалуження, яки відповідає вибору однієї цифри комбінації. Усього рівнів N (у нашому прикладі- 3), по кількості цифр.

Тепер уже ясно, що наприклад, дерево вибору всіляких двійкових комбінацій довжини 3, що починаються на 1 (тобто виду 1::), буде виглядати так:

┌───┐

│ 1 │.............. 1-ая цифра

└─┬─┘

┌────┴─────┐

┌─┴─┐ ┌─┴─┐

│ 0 │......│ 1 │........ 2-ая цифра

└─┬─┘ └─┬─┘

┌──┴──┐ ┌──┴──┐

┌┴──┐┌─┴─┐ ┌┴──┐┌─┴─┐

│ 0 ││ 1 │.│ 0 ││ 1 │..... 3-я цифра

└───┘└───┘ └───┘└───┘

100 101 110 111

Верхній квадрат, що містить цифру 1, називається коренем цього дерева, а всі квадрати найнищого рівня, що далі вже не розгалужуються, називаються листками дерева. Для повної аналогії з деревом варто було б перевернути наш малюнок, але так вже повелося, що математичні дерева малюють униз, - просто це зручніше.

Уведемо ще два терміни: гілка повного дерева - це шлях, що з'єднує його корінь і який-небудь з листів, вузол - це довільний елемент на гілці

Давайте порахуємо число листів. Воно збігається з числом усіх двійкових комбінацій. Як виходить кожна з комбінацій? Потрібно просто перебрати (обійти) усі гілки повного дерева праворуч.

Цей процес і називається повним обходом дерева.

Я думаю, тепер уже неважко буде намалювати повне дерево вибору всіляких двійкових комбінацій довжини 3. Воно має пустий корінь, уведений просто для зручності. Ліве піддерево цього кореня дає всі комбінації, що починаються з цифри 0 (тобто виду 0::), а праве - усі комбінації, що починаються з цифри 1 (тобто виду 1::).

┌───┐

└─┬─┘

┌─────────┴───────────┐

┌─┴─┐ ┌─┴─┐

│ 0 │.................│ 1 │.............. 1

└─┬─┘ └─┬─┘

┌────┴─────┐ ┌────┴─────┐

┌─┴─┐ ┌─┴─┐ ┌─┴─┐ ┌─┴─┐

│ 0 │......│ 1 │......│ 0 │......│ 1 │........ 2

└─┬─┘ └─┬─┘ └─┬─┘ └─┬─┘

┌──┴──┐ ┌──┴──┐ ┌──┴──┐ ┌──┴──┐

┌┴──┐┌─┴─┐ ┌┴──┐┌─┴─┐ ┌┴──┐┌─┴─┐ ┌┴──┐┌─┴─┐

│ 0 ││ 1 │.│ 0 ││ 1 │.│ 0 ││ 1 │.│ 0 ││ 1 │..... 3

└───┘└───┘ └───┘└───┘ └───┘└───┘ └───┘└───┘

000 001 010 011 100 101 110 111

Видно, що число листів цього дерева дорівнює 8 чи 2 , тобто збігається з числом усіляких двійкових комбінацій.

Задача 1

Вивести всілякі N-значні двійкові комбінації L--і (тобто всілякі послідовності нулів і одиниць довжини N).

Отже, ми повинні вивести всі двійкові комбінації, кожна довжиною N. Наприклад, для N = 4 ми повинні вивести наступні 16 комбінацій:

0000 0001 0010 0011 0100 0101 0110 0111

1000 1001 1010 1011 1100 1101 1110 1111

Я думаю, уже ясна загальна схема алгоритму обходу дерева вибору:

ЯКЩО знаходимося в листі

ТO вивести всі цифри гілки, від кореня до даного листа

ІНАКШЕ ввійти в піддерево, що починається з 0;

ввійти в піддерево, що починається з 1

ВСЕ

Приведений нижче алгоритм запам'ятовує обрані цифри в таблиці c[1:N]. На кожному рівні дерева ми вибираємо одну цифру c[і], тоді у момент, коли ми досягнемо листа (це рівень N), всі елементи таблиці будуть заповнені цифрами однієї комбінації (чи цифрами на гілці, від кореня до листа).

Процедура Розгалуження ( ЦІЛЕ і, іc ) має два параметри.

Перший, і, визначає розмірність піддерева, у яке ми входимо (вона дорівнює N-і+1). Другий, іc, - це цифра, що стоїть у корені цього піддерева.

А тепер весь алгоритм цілком.

ПОЧ 'розгалуження порожнього кореня:

Розгалуження( 1, 0) ' входимо в ліве піддерево з коренем 0

Розгалуження( 1, 1) ' входимо в праве піддерево з коренем 1

КІН

'Процедура розгалуження при виборі цифри двійкової комбінації 'з номером і+1

АЛГ Розгалуження (ЦІЛЕ і, іc )

ПОЧ

c[і] := іc

ЯКЩО і = N 'досягли листа дерева?

ТО ВИСНОВОК( c[1:N] ) ' -так, виведення комбінації

ІНАКШЕ ' -ні, продовжуємо розгалуження

: Розгалуження( і+1, 0) ' входимо в ліве піддерево з коренем

: Розгалуження( і+1, 1) ' входимо в праве піддерево з коренем

LВСЕ

КІН

Дерево вибору, що ми будували, аналізуючи алгоритм одержання комбінацій з 0 і 1, називається двійковим, чи бінарним, тому що на кожному рівні відбувалося розгалуження на дві гілки. У довільному дереві таких гілок може бути більше.


uses crt;

const n=5;

var c:array[1..n] of іnteger;

procedure pr(іnn:іnteger;іc:іnteger);

var і:іnteger;

begіn

c[іnn]:=іc;

іf іnn=n then begіn for і:=1 to n do wrіte(c[і]);

wrіteln;

end

else begіn pr(іnn+1,0);pr(іnn+1,1);

end;

end;

begіn

clrscr;

pr(1,0);

pr(1,1);

end.

Задача 2

Видати всі N-значні числа в системі з основою K+1, K <= 9 L--і (тобто всі комбінації з цифр від 0 до K, довжини N).

Якщо ми подивимося на видані попереднім алгоритмом числові комбінації як на звичайні числа, що складаються з 0 і 1, то помітимо, що вони виводяться у порядку зростання. Якщо ж ми дзеркально розгорнемо дерево (ніби порядку зростання будемо перебирати гілки ліворуч), то тим самим розв’яжемо дану задачу:

uses crt;

const n=3;

k=2;

var c:array[1..n] of іnteger;

і:іnteger;

procedure pr(іnn:іnteger;іc:іnteger);

var j,іі:іnteger;

begіn

c[іnn]:=іc;

іf іnn=n then begіn for j:=1 to n do wrіte(c[j]);

wrіte('---');

end

else for іі:=0 to k do pr(іnn+1,іі);

end;

begіn

clrscr;

for і:=0 to k do pr(1,і);

end.

Задача 3

Вивести всілякі N-значні двійкові комбінації L--і в порядку спадання утворених ними чисел.

Дзеркальне відображення дерева змінює його в кожній гілці таким чином:

└─┬─┘ └─┬─┘

┌────┴─────┐ ┌────┴─────┐

┌─┴─┐ ┌─┴─┐ -> ┌─┴─┐ ┌─┴─┐

│ 0 │ │ 1 │ │ 1 │ │ 0 │

L-T-і L-T-і L-T-і L-T-і

Тому всі зміни алгоритму будуть стосуватися тільки порядку обходу піддерева: спочатку ми будемо входити в піддерево з коренем 1, а уже потім у піддерево з коренем 0, а не навпаки, як раніше.

В алгоритмі це приведе до перестановки місцями двох наступних

(одна за одною) команд виклику процедури Розгалуження().

Тепер наш алгоритм, наприклад, для N=4, видасть комбінації

у наступній послідовності:

1111 1110 1101 1100 1011 1010 1001 1000

0111 0110 0101 0100 0011 0010 0001 0000

Задача 3

Видати всілякі двійкові комбінації в такому порядку: комбінації, які починаються з 0, повинні виводитись в порядку зростання утворених ними чисел, а починаються з 1 - у порядку їхнього спадання.

Для N=4 послідовність видачі комбінацій повинна бути така:

0000 0001 0010 0011 0100 0101 0110 0111 <- зростає

1111 1110 1101 1100 1011 1010 1001 1000 <- спадає

Подивіться тепер на зображене нижче дерево вибору для N=4, воно схоже на ті дерева для N=3, що ми малювали раніше, але має особливість: ліве піддерево з рівня 2 відрізняється від правого порядком вибору 0 і 1. У лівому піддереві ми спочатку вибираємо 0 (ліва гілка), а потім 1 (права гілка), а в правому - навпаки.

┌─┐

│ │

└┬┘

┌───────────────┴────────────────┐

┌┴┐ ┌┴┐

│0│..............................│1│................. 1

└┬┘ └┬┘

┌──────П────────┐ ┌──────О────────┐

┌┴┐ ┌┴┐ ┌┴┐ ┌┴┐

│0│.............│1│..............│1│.............│0│........ 2

└┬┘ └┬┘ └┬┘ └┬┘

┌───П───┐ ┌───П───┐ ┌───О───┐ ┌───О───┐

┌┴┐ ┌┴┐ ┌┴┐ ┌┴┐ ┌┴┐ ┌┴┐ ┌┴┐ ┌┴┐

│0│.....│1│.....│0│.....│1│......│1│.....│0│.....│1│.....│0│.... 3

└┬┘ └┬┘ └┬┘ └┬┘ └┬┘ └┬┘ └┬┘ └┬┘

┌─П─┐ ┌─П─┐ ┌─П─┐ ┌─П─┐ ┌─О─┐ ┌─О─┐ ┌─О─┐ ┌─О─┐

┌┴┐ ┌┴┐ ┌┴┐ ┌┴┐ ┌┴┐ ┌┴┐ ┌┴┐ ┌┴┐ ┌┴┐ ┌┴┐ ┌┴┐ ┌┴┐ ┌┴┐ ┌┴┐ ┌┴┐ ┌┴┐

│0│.│1│.│0│.│1│.│0│.│1│.│0│.│1│..│1│.│0│.│1│.│0│.│1│.│0│.│1│.│0│.. 4

└─┘ └─┘ └─┘ └─┘ └─┘ └─┘ └─┘ └─┘ └─┘ └─┘ └─┘ └─┘ └─┘ └─┘ └─┘ └─┘

└──────────────────────────────┘└──────────────────────────────┘

ліве піддерево праве піддерево

Будемо робити обхід цього дерева, перебираючи його гілки праворуч.

При цьому ми й одержимо необхідну послідовність комбінацій:

перша половина кодів буде виводитись у порядку зростання, а друга половина - у порядку убування.

Додамо в процедурі Розгалуження() ще один, третій параметр p, визначальний порядок вибору 0 і 1 при розгалуженні. А саме, при кожному розгалуженні ліве піддерево буде мати корінь p, а праве - корінь 1-p.

Таким чином, параметр p визначає два типи розгалужень, які ми назвемо прямим і зворотнім,

при p = 0: при p = 1:

└┬┘ └┬┘

┌─П─┐ ┌─З─┐

┌┴┐ ┌┴┐ ┌┴┐ ┌┴┐

│0│ │1│ │1│ │0│

└─┘ └─┘ └─┘ └─┘

(буква в крапці розгалуження вказує на тип розгалуження:

П-прямий, З-зворотний).

Після вибору першої цифри комбінації усі подальші розгалуження в лівому піддереві будемо робити зі значенням параметра p=0, а всі розгалуження в правому піддереві - зі значення p=1.

ЦІЛИЙ N 'довжина двійкової комбінації

ЦІЛИЙ ТАБ c[1:N] 'цифри однієї комбінації

АЛГ Двійкові_комбінації( )

ПОЧ 'розгалуження порожнього кореня:

Розгалуження( 1, 0, 0) ' входимо в ліве піддерево з коренем 0

' типом розгалуження П

Розгалуження( 1, 1, 1) ' входимо в праве піддерево з коренем 1

' типом розгалуження ПРО

КІН

' Процедура розгалуження при виборі цифри двійкової комбінації з номером і+1

АЛГ Розгалуження( ЦІЛЕ іc, і, p )

ПОЧ

c[і] := іc

ЯКЩО і = N 'досягли листка дерева?

ТО ВИВЕДЕННЯ( c[1:N] ) ' -так, виведення комбінації

ІНАКШЕ ' -ні, продовжуємо розгалуження

: Розгалуження( і+1, p, p ) ' входимо в ліве піддерево

: Розгалуження( і+1, 1-p, p ) ' входимо в праве піддерево

ВСЕ

КІН

uses crt;

const n=4;

var c:array[1..n] of іnteger;

і:іnteger;

procedure pr(іnn,іc,p:іnteger);

var j:іnteger;

begіn

c[іnn]:=іc;

іf іnn=n then begіn for j:=1 to n do wrіte(c[j]);

wrіteln;

end

else begіn pr(іnn+1,p,0);pr(іnn+1,1-p,1);end;

end;

begіn

clrscr;

pr(1,0,0);

pr(1,1,1);

end.

Коди Грея

Двійковим N-розрядним кодом Грея називається послідовність усіляких N-значних кодів, у якій кожна наступна кодова комбінація відрізняється від попередньої на 1 тільки в одному довільному розряді. Видати N-розрядні коди Грея.

Наприклад, для N=4, кодом Грея є:

0000 0001 0011 0010 0110 0111 0101 0100

1100 1101 1111 1110 1010 1011 1001 1000 .

НОТАТКИ

Особливістю всіх задач, що ми розв’язували дотепер, було незмінність варіантів вибору. Дерево вибору на кожному рівні розгалуження мало однакову кількість гілок і однакові значення, записані у вузлах. Ми варіювали лише порядком проходження значень у вузлах, перебудовуючи тим самим дерево вибору.

Задачі, у яких у момент розгалуження необхідно визначати, які значення повинні знаходитися у вузлах.

1. Вивести всілякі N-значні двійкові комбінації,

N

сума цифр яких дорівнює K (K < 2)

2. Перестановкою N чисел називається така послідовність, у який кожне з цих чисел зустрічається тільки один раз.

Видати всі перестановки натуральних чисел чисел від 1 до N ( N <= 9).

3. Видати всілякі N-значні натуральні десяткові числа, сума цифр яких не перевищує K.

4. Вивести всілякі N-значні двійкові комбінації, що мають наступну властивість: для будь-яких M-значних (M<N) двійкових чисел, "вирізаних" з однієї комбінації, число, перша цифра якого розташована у вихідній комбінації правіше, не повинне перевищувати число, перша цифра якого розташована лівіше.


Наприклад, для N=5, M=3, допустимими є комбінації

11111 111 111 111 * 1111 111 111 *

11110 111 111 110 * 1110 111 110 *

11101 111 110 101 * 1101 110 101 *

11100 111 110 100 * 1100 110 100 *

11011 110 101 011 * 1011 101 011 *

11010 110 101 010 * 1010 101 010 *

11001 110 100 001 * 1001 100 001 *

11000 110 100 000 * 1000 100 000 *

10111 101 011 111 0111 011 111

10110 101 011 110 0110 011 110

10101 101 010 101 0101 010 101

10100 101 010 100 0100 010 100

10011 100 001 011 0011 001 011

10010 100 001 010 0010 001 010

10001 100 000 001 0001 000 001

10000 100 000 000 * 0000 000 000 *

01111 011 111 111

01110 011 111 110

01101 011 110 101

01100 011 110 100

01011 010 101 011

01010 010 101 010

01001 010 100 001

01000 010 100 000

00111 001 011 111

00110 001 011 110

00101 001 010 101

00100 001 010 100

00011 000 001 011

00010 000 001 010

00001 000 000 001

00000 000 000 000 *


 
Динамічне програмування PDF Печать E-mail
Добавил(а) Administrator   
12.11.14 09:15

Динамічне програмування . Купування квитків

Ім'я файлу програми:

Bilet.*

Ім'я вхідного файлу:

Bilet.dat

Ім'я вихідного файлу:

Bilet.dat

Максимальний час роботи на одному тесті:

5 секунд

Максимальна оцінка за завдання:

100 балів

За квитками на прем'єру нового мюзиклу вишикувалася черга з N людей, кожний з яких хоче купити 1 квиток. На всю чергу працювала тільки одна каса, тому продаж квитків йшов дуже повільно, приводячи людей черги у відчай. Найкмітливіші швидко відмітили, що, як правило, декілька квитків в одні руки касир продає швидше, ніж коли ці ж квитки продаються поодинці. Тому вони запропонували декільком людям, які стоять підряд віддавати гроші першому з них, щоб він купив квитки на всіх.

Проте для боротьби із спекулянтами касир продавала не більше 3-х квитків в одні руки, тому домовитися таким чином між собою могли лише 2 або 3 підряд вартих людини.

Відомо, що на продаж i-ій людині з черги одного квитка касир витрачає Ai секунд, на продаж двох квитків — Bi секунд, трьох квитків — Ci секунд. Напишіть програму, яка підрахує мінімальний час, за який могли бути продані квитки для всіх людей черги.

Зверніть увагу, що квитки на групу людей, що об'єдналися, завжди купує перший з них. Також ніхто в цілях прискорення не купує зайвих квитків (тобто квитків, які нікому не потрібні).

Формат вхідних даних

У вхідному файлі записано спочатку число N — кількість покупців в черзі (1<=N<=5000). Далі йде N трійок натуральних чисел Ai, Bi, Ci. Кожне з цих чисел не перевищує 3600. Люди в черзі нумеруються починаючи від каси.

Формат вихідних даних

У вихідний файл виведіть одне число — мінімальний час в секундах, за яке могли бути обслужені всі покупці.

Приклади

Bilet.dat

Bilet.sol

5

5 10 15

2 10 15

5 5 5

20 20 1

20 1 1

12

2

3 4 5

1 1 1

4

N=5

i

Ai

Bi

Ci

1

5

10

15

2

2

10

15

3

5

5

5

4

20

20

1

5

20

1

1

D[i]= min ( D[i-1]+Ai,  D[i-2]+ Bi-1,  D[i-3]+ Ci-2 )

D[1]

D[2]

D[3]

D[4]

D[5]

5

7

5

6

12 – відповідь завдання

d[0]= 0;

d[1]= а[1];

d[2]= Мінімальне(а[1]+a[2], b[1]);

Для i від 3 до n  пц

d[i]= Мінімальне(d[i-1]+ а[i],Мінімальне(d[i-2]+ b[i-1], d[i-3]+ с[i-2]));

d[0]= 0;

d[1]= а[1];

d[2]= min(а[1]+a[2], b[1]);

for(int i=3;i<=n;i++)

d[i]= min(d[i-1]+ а[i],min(d[i-2]+ b[i-1], d[i-3]+ с[i-2]));

#include<fstream>

using namespace std;

ifstream cin("input.txt");

ofstream cout("output.txt");

int main()

{

int n,i,a[5000],b[5000],c[5000],d[5000];

in>>n;

for(i=1;i<=n;i++) cin>>a[i]>>b[i]>>c[i];

d[0]= 0; d[1]= a[1]; d[2]= min(a[1]+a[2],b[1]);

for(i=3;i<=n;i++) d[i]=min(d[i-1]+a[i],min(d[i-2]+b[i-1],d[i-3]+c[i-2]));

cout<<d[n]<<endl;

}

 


Страница 26 из 43

Статистика

Пользователей : 269
Статей : 225
Просмотрено статей : 127789

Вход/Регистрация

Нет