www.agora.ro

Beijing, China...

IOI 2000

Vă prezentăm enunțurile celor șase probleme cu care s-au confruntat 272 de concurenți reprezentând 72 de țări participante la cea de-a XII-a Olimpiadă Internațională de Informatică care s-a desfășurat la Beijing, în China.

P070001: Parcare auto

Un centru de parcare auto situat lângă Marele Zid este format dintr-un șir (rând) lung de locuri de parcare. O extremitate a acestui rând este considerată ca fiind cea din stânga, iar cealaltă cea din dreapta. Toate locurile de parcare sunt ocupate de automobile. Fiecare automobil este de un anumit tip, iar unele automobile din șir pot avea tipuri identice. Tipurile sunt identificate prin valori întregi. Un număr de muncitori decide să ordoneze automobilele parcate astfel încât tipurile respective să fie în ordine crescătoare de la stânga la dreapta, folosind metoda descrisă în continuare.

O rundă constă în următoarele operații: muncitorii respectivi scot simultan câte o mașină din șir, iar după această fază parchează mașinile scoase în locurile disponibile. Într-o rundă, nu este obligatoriu ca toți muncitorii să participe la operație. Pentru eficiență, este preferabil ca ordonarea să se realizeze într-un număr minim de runde.

Fie N numărul automobilelor, iar W numărul muncitorilor. Scrieți un program care, cunoscând tipul fiecărui automobil parcat și numărul muncitorilor, realizează or-donarea automobilelor într-un număr de runde care nu depășește valoarea éN/(W-1)ù, unde é ù reprezintă partea întreagă superioară. Menționăm că numărul minim de runde nu este niciodată mai mare decât éN/(W-1)ù.

Să considerăm următorul exemplu. Sunt 10 automobile parcate, având tipurile 1, 2, 3 și 4, și sunt disponibili 4 muncitori. Plasarea inițială a automobilelor redată prin tipul lor de la stânga la dreapta este:

2 3 3 4 4 2 1 1 3 1.

Numărul minim de runde este trei, rundele putând fi de exemplu, următoarele:

2 1 1 4 4 2 3 3 3 1 - după runda 1;

2 1 1 2 4 3 3 3 4 1 - după runda 2;

1 1 1 2 2 3 3 3 4 4 - după runda 3.

Date de intrare

Numele fișierului de intrare este CAR.IN. Prima linie conține trei numere întregi. Primul întreg este numărul N al automobilelor, 1 Ł N Ł 20.000. Al doilea întreg este numărul M de tipuri, 2 Ł M Ł 50. Tipurile de mașini sunt identificate prin întregi de la 1 la M. Există cel puțin câte un automobil de fiecare tip. Al treilea întreg este numărul W de muncitori, 2 Ł W Ł M. Linia a doua a fișierului de intrare conține N numere întregi, unde al i-lea număr reprezintă tipul celui de-al i-lea automobil din șirul de locuri de parcare, de la stânga la dreapta.

Date de ieșire

Numele fișierului de ieșire este CAR.OUT. Prima linie conține un singur număr întreg R, care reprezintă numărul de runde din soluție. Următoarele R linii descriu rundele în ordine de la 1 la R. Pe fiecare linie, primul număr întreg este numărul C al automobilelor mutate în runda respectivă. Urmează 2C numere întregi, formând C perechi corespunzătoare deplasărilor mașinilor, utilizând pozițiile lor. Pozițiile sunt redate prin numere de la 1 la N, pornind de la capătul din stânga. Primele două numere întregi formează o pereche care descrie reamplasarea unui automobil: primul întreg reprezintă poziția de la începutul rundei, iar al doilea - poziția la sfârșitul rundei. Următorii doi întregi formează o pereche care descrie cum este mutat un alt automobil ș.a.m.d. Întrucât pot exista mai multe soluții distincte pentru aceste R linii, programul va scrie în fișierul de ieșire numai una din ele.

Exemplu

CAR.IN

10 4 4

2 3 3 4 4 2 1 1 3 1

CAR.OUT

3

4 2 7 3 8 7 2 8 3

3 4 9 9 6 6 4

3 1 5 5 10 10 1

P070002: Puterea mediană

Un experiment implică N obiecte, etichetate de la 1 la N. Se știe că N este impar. Fiecărui obiect i se atașează o informație (numită putere) care este necunoscută și este exprimată printr-un număr natural; puterile obiectelor sunt distincte. Fiecare putere Y satisface relația 1 Ł Y Ł N. Obiectul de putere mediană este obiectul X cu proprietatea că numărul de obiecte cu putere mai mică decât puterea lui X este egal cu numărul obiectelor cu putere mai mare decât puterea lui X. Scrieți un program care determină obiectul de putere mediană. Din nefericire, singurul mod de a compara puterile este bazat pe un dispozitiv care, pentru trei obiecte distincte date, determină pe acela dintre ele care are puterea mediană.

Biblioteci

Este dată biblioteca device care conține trei subprograme:

- GetN - trebuie apelat o singură dată, la început, nu are argumente și returnează valoarea N.

- Med3 - trebuie apelat cu etichetele a trei obiecte distincte ca argumente și returnează eticheta obiectului de putere mediană.

- Answer - trebuie apelat o singură dată, la sfârșit, și are ca argument eticheta unui obiect; acest obiect ar trebui să fie cel care are puterea mediană; această operație este cea care încheie executarea programului.

Biblioteca device este folosită pentru a crea două fișiere text: MEDIAN.OUT și MEDIAN.LOG. Prima linie a fișierului MEDIAN.OUT conține un întreg indicând eticheta obiectului transmis ca parametru în apelarea subprogramului Answer. A doua linie conține un număr întreg care indică numărul de apeluri ale subprogramului Med3 efectuate de programul dumneavoastră. Dialogul între program și bibliotecă este memorat în fișierul MEDIAN.LOG.

Programatorii în Pascal trebuie să includă în codul sursă instrucțiunea

uses device;

Programatorii în C/C++ trebuie să includă în codul sursă instrucțiunea

#include "device.h"

Trebuie creat proiectul MEDIAN.PRJ și apoi adăugate fișierele MEDIAN.C (MEDIAN.CPP) și DEVICE.OBJ în acest proiect.

Experimentare

Lucrul cu biblioteca se poate experimenta creând un fișier text DEVICE.IN. Fișierul trebuie să conțină două linii. Prima linie conține un întreg: numărul N al obiectelor. A doua linie conține numerele întregi de la 1 la N într-o ordine oarecare, al i-lea întreg reprezentând puterea obiectului etichetat cu i.

Exemplu

DEVICE.IN

5

2 5 4 3 1

Fișierul descrie o intrare cu cinci obiecte și puterile lor:

Etichetă: 1 2 3 4 5

Putere: 2 5 4 3 1

O secvență corectă este formată din următoarele cinci apeluri:

1. GetN (în Pascal) sau GetN() (în C/C++) - returnează 5.

2. Med3(1,2,3) - returnează 3.

3. Med3(3,4,1) - returnează 4.

4. Med3(4,2,5) - returnează 4.

5. Answer(4)

Restricții

  • Numărul N al obiectelor este impar și 5 Ł N Ł 1499.
  • Orice etichetă i satisface relația 1 Ł i Ł N.
  • Orice putere Y satisface relația 1 Ł Y Ł N; puterile sunt distincte.
  • Numele bibliotecii Pascal este device.tpu.
  • Declarațiile subprogramelor Pascal sunt

function GetN:Integer;

function Med3(x,y,z:Integer):Integer;

procedure Answer(m:Integer);

  • Numele bibliotecilor C/C++: device.h, device.obj (folosiți modelul de memorie large).
  • Header-ele funcțiilor C/C++ sunt:

int GetN(void);

int Med3(int x,int y,int z);

void Answer(int m);

  • La o rulare sunt permise cel mult 7777 de apeluri ale subprogramului Med3.
  • Programul dumneavoastră nu trebuie să conțină instrucțiuni explicite de citire/scriere din/în vreun fișier; citirile/scrierile se realizează prin intermediul subprogramelor din biblioteci.

P070003: Palindrom

Un palindrom este un șir simetric de caractere, adică un șir care, citit atât de la stânga la dreapta cât și de la dreapta la stânga, este identic. Scrieți un program care, pentru un șir dat, determină numărul minim de caractere care trebuie inserate în el, inclusiv la capete, pentru a obține un palindrom. De exemplu, inserând două caractere, șirul Ab3bd poate fi transformat într-un palindrom (dAb3bAd sau Adb3bdA). Se observă că inserarea a mai puțin de două caractere nu duce la obținerea unui palindrom.

Date de intrare

Fișierul de intrare este PALIN.IN. Prima linie conține un număr întreg: lungimea N a șirului, 3 Ł N Ł 5000. A doua linie conține un șir de lungime N. Șirul este format din literele mari de la 'A' la 'Z', literele mici de la 'a' la 'z' și cifrele de la '0' la '9'. Literele mari și mici sunt considerate distincte.

Date de ieșire

Fișierul de ieșire este PALIN.OUT. Acesta trebuie să conțină un singur număr întreg, care reprezintă minimul căutat.

Exemplu

PALIN.IN

5

Ab3bd

PALIN.OUT

2

P070004: Descompunere în blocuri

Un cub unitate este un cub de dimensiuni 1 Ž 1 Ž 1; coordonatele x, y, z ale colțurilor sale sunt numere întregi. Două cuburi unitate se consideră alipite dacă au o față comună. Prin obiect tridimensional înțelegem o mulțime nevidă de cuburi unitate alipite două câte două (vezi figura 1). Volumul obiectului este numărul cuburilor unitate din care este format.

Un bloc este un obiect cu volumul cel mult egal cu 4. Două blocuri sunt de același tip dacă pot fi obținute unul din altul prin translații și rotații (dar nu prin oglindire). Există exact 12 tipuri de blocuri (vezi figura 2). Culorile din figură nu prezintă importanță; ele sunt folosite doar pentru a prezenta mai clar structura obiectelor.

Printr-o descompunere a unui obiect S se înțelege o mulțime D de blocuri din care poate fi reconstituit obiectul S. Precizăm că două blocuri din D nu pot avea un cub unitate în comun.

Scrieți un program care, pentru o descriere a tipurilor de blocuri și un obiect S, determină acea descompunere a lui S care cuprinde un număr minim de blocuri având tipurile date. Trebuie determinate doar tipurile blocurilor, așa cum apar în descompunere.

Date de intrare

În fișierul de intrare un cub unitate este descris prin trei numere întregi x, y, z, reprezentând coordonatele acelui colț pentru care suma x + y + z este minimă.

Fișierul de intrare TYPES.IN conține descrierea celor 12 tipuri de blocuri din figura 2, în ordinea numerelor atașate tipurilor blocurilor. Acest fișier este folosit pentru toate testele. Fiecare bloc este descris printr-o secvență de linii consecutive. Prima linie conține numărul I al tipului de bloc (1 Ł I Ł 12). A doua linie conține volumul blocului (1 Ł V Ł 4). Următoarele V linii conțin cuburile unitate componente, prin precizarea întregilor x, y, z, care le descriu (1 Ł x, y, z Ł 4).

Fișierul BLOCK.IN conține descrierea obiectului care trebuie descompus. Prima linie conține volumul V al obiectului (1 Ł V Ł 50). Următoarele V linii conțin, fiecare, un triplet de numere întregi x, y, z ce descrie câte un cub unitate din componența obiectului (1 Ł x, y, z Ł 7).

Date de ieșire

Fișierul de ieșire este BLOCK.OUT. Prima linie va conține întregul M, reprezentând numărul minim de blocuri în care obiectul descris în BLOCK.IN poate fi descompus.

A doua linie va conține M numere, reprezentând numerele atașate tipurilor de blocuri în care obiectul a fost descompus.

Dacă există mai multe soluții, în fișier se va scrie una singură.

Eexemplu

TYPES.IN BLOCKS.IN

1 18

1 2 1 1

1 1 1 4 1 1

2 2 3 1

2 4 3 1

1 1 1 2 1 2

1 2 1 3 1 2

3 4 1 2

3 1 2 2

1 1 1 2 2 2

1 2 1 3 2 2

1 3 1 4 2 2

4 2 3 2

3 3 3 2

1 1 1 4 3 2

1 2 1 4 2 3

1 1 2 4 2 4

5 4 2 5

4 5 2 5

1 1 1

1 2 1 BLOCK.OUT

1 3 1 5

1 4 1 7 10 2 10 12

6

4

1 1 1

1 2 1

1 1 2

1 2 2

7

4

1 1 1

1 2 1

1 1 2

1 1 3

8

4

1 1 1

1 2 1

1 3 1

1 2 2

9

4

1 2 1

1 3 1

1 1 2

1 2 2

10

4

2 1 1

1 2 1

2 2 1

2 1 2

11

4

1 1 1

1 2 1

2 2 1

1 1 2

12

4

2 2 1

2 1 2

1 2 2

2 2 2

Note

1. Fișierul BLOCK.IN corespunde "calului" din figura 1.

2. Alte variante pentru cea de-a doua linie din fișierul de ieșire sunt:

2 7 10 11 12

2 7 11 11 12

4 4 7 10 11

4 4 9 10 11

P070005: Oficii poștale

Se consideră o autostradă dreaptă cu orașe situate de-a lungul ei. Autostrada reprezintă o axă având numai coordonate întregi, deci poziția fiecărui oraș este identificată printr-un număr întreg. Nu există două orașe situate pe aceeași poziție. Distanța între două poziții este valoarea absolută a diferenței coordonatelor lor.

În unele orașe, dar nu neapărat în toate, urmează a fi amplasate oficii poștale. Oficiile poștale pot fi situate doar în orașe, iar fiecare oraș poate avea cel mult un oficiu poștal. Dându-se numărul de oficii poștale, se caută o amplasare a lor astfel încât suma tuturor distanțelor între fiecare oraș și oficiul poștal cel mai apropiat de acesta să fie minimă.

Scrieți un program care, dându-se pozițiile orașelor și numărul de oficii poștale, determină atât cea mai mică sumă posibilă a distanțelor de la fiecare oraș la oficiul poștal cel mai apropiat de acesta, cât și pozițiile unde sunt amplasate oficiile poștale astfel încât să se obțină această sumă minimă.

Date de intrare

Fișierul de intrare este POST.IN. Prima linie conține două numere întregi: primul reprezintă numărul V al orașelor, 1 Ł V Ł 300, iar al doilea reprezintă numărul P al oficiilor poștale, 1 Ł P Ł 30 și P Ł V. A doua linie conține V numere întregi în ordine crescătoare, reprezentând pozițiile orașelor. Pentru fiecare poziție X avem 1 Ł X Ł 10000.

Date de ieșire

Fișierul de ieșire este POST.OUT. Prima linie conține un întreg S, reprezentând cea mai mică sumă posibilă a distanțelor de la fiecare oraș la oficiul poștal cel mai apropiat de acesta, conform descrierii din cea de a doua linie. A doua linie conține P întregi în ordine crescătoare. Acești întregi reprezintă pozițiile orașelor în care sunt amplasate oficiile poștale. Dacă există mai multe soluții, fișierul de ieșire va conține una singură.

Exemplu

POST.IN

10 5

1 2 3 6 7 9 11 22 44 50

POST.OUT

9

2 7 22 44 50

P070005: Ziduri

Într-o țară au fost construite ziduri astfel încât fiecare zid leagă două orașe. Zidurile nu se intersectează și împart țara în zone închise. Deplasarea dintr-o zonă în alta se poate face trecând dintr-un oraș într-un oraș vecin sau traversând ziduri. Între oricare două orașe A și B există cel mult un zid, având drept capete pe A și pe B. Rețeaua de ziduri este conexă.

În țară există un club ai cărui membrii locuiesc în orașe diferite. În fiecare oraș locuiește cel mult un membru al clubului.

Deseori membrii clubului doresc să se întâlnească undeva în afara orașelor, în una dintre zone. Membrii clubului călătoresc cu biciclete. Din cauza traficului intens ei nu vor să treacă prin orașe și astfel sunt nevoiți să traverseze ziduri. Traseul unui membru către o zonă nu va trece prin nic un oraș cu excepția celui de plecare. Evident, numărul de traversări de ziduri trebuie să fie cât mai mic.

Pentru a ajunge în zona de întâlnire, fiecare membru traversează un număr de ziduri, eventual nici unul. Ei doresc să stabilească o zonă (numită optimă) de întâlnire, pentru care suma acestor numere, numită sumă de traversare, este minimă.

Orașele sunt etichetate cu numere întregi de la 1 la N, unde N este numărul de orașe. În figura 1 vârfurile reprezintă orașe, iar liniile care le leagă reprezintă ziduri. Presupunem că cei trei membri ai clubului locuiesc în orașele 3, 6 și 9.

Zona optimă și traseele respective pentru fiecare membru sunt indicate în figura 2. Suma de traversare minimă este 2: membrul din orașul 9 traversează zidul dintre orașele 2 și 4, iar cel din orașul 6 zidul dintre orașele 4 și 7.

Scrieți un program care, pornind de la descrierea orașelor, a zonelor și a orașelor în care locuiesc membrii clubului, determină zona optimă și suma de traversare minimă.

Date de intrare

Numele fișierului de intrare este WALLS.IN. Prima linie conține un întreg: numărul M al zonelor, 2 Ł M Ł 200. Linia a doua conține un întreg: numărul N al orașelor, 3 Ł N Ł 250. Linia a treia conține un întreg: numărul L ai membrilor clubului, 1 Ł L Ł 30, L Ł N. Linia a patra conține, în ordine crescătoare, L numere întregi distincte: etichetele orașelor în care locuiesc membrii clubului.

În continuare fișierul de intrare conține 2M linii, câte o pereche de linii pentru fiecare zonă: primele două dintre cele 2M linii descriu prima zonă, următoarele două linii descriu a doua zonă ș.a.m.d. Într-o pereche de linii, prima conține numărul I al orașelor situate pe frontiera zonei respective. A doua linie din pereche conține cele I etichete ale acestor orașe, scrise în ordinea parcurgerii frontierei zonei respective în sensul acelor de ceasornic.

Ultima zonă din fișierul de intrare este aceea care împrejmuiește toate orașele și toate celelalte zone; de această dată ordinea etichetelor este specificată în sensul invers acelor de ceasornic. Ordinea zonelor din fișierul de intrare determina etichetarea acestora: prima zonă are eticheta 1, zona a doua are eticheta 2 ș.a.m.d.

Accentuăm faptul că fișierul de intrare conține toate zonele formate de orașe și ziduri, precum și zona formată de zidurile externe.

Date de ieșire

Numele fișierului de ieșire este WALLS.OUT. Prima linie conține un întreg: suma de traversare minimă. Linia a doua conține un întreg: eticheta zonei optime. Întrucât pot fi mai multe soluții distincte, programul va determina numai una dintre ele.

Exemplu

WALLS.IN

10

10

3

3 6 9

3

1 2 3

3

1 3 7

4

2 4 7 3

3

4 6 7

3

4 8 6

3

6 8 7

3

4 5 8

4

7 8 10 9

3

5 10 8

7

7 9 10 5 4 2 1

WALLS.OUT

2

3

[cuprins]