2458 - Hobby

De la Universitas MediaWiki
Versiunea pentru tipărire nu mai este suportată și poate avea erori de randare. Vă rugăm să vă actualizați bookmarkurile browserului și să folosiți funcția implicită de tipărire a browserului.

Enunt

În școala lui Gigel copiii se pregătesc pentru vacanță. Ei vor să-și petreacă timpul liber în mod diferit în funcție de hobby-urile pe care le au. În concluzie, urmează să formeze grupuri, pe baza preferințelor. Totuși, a apărut o problemă. Unii sunt dispuși să renunțe la propriul hobby și preferă să facă parte dintr-un grup din care face parte și un anumit prieten al lor. În școala lui Gigel sunt n copii, numerotați de la 1 la n.

Cerinţa

Cunoscând prietenul preferat și hobby-ul fiecărui copil, scrieți un program care determină numărul grupurilor care se vor forma și numărul grupurilor formate din copii care au hobby-uri identice; doi copii vor face parte din același grup, dacă cel puțin unul din cei doi l-a numit pe celălalt ca prieten.

Date de intrare

Pe prima linie a fișierului de intrare hobby1.in se află un număr natural n, reprezentând numărul copiilor. Pe fiecare din următoarele n linii se află câte o pereche de numere naturale, unde primul număr reprezintă numărul de ordine al copilului având ca prieten preferat copilul identificat cu cel de al doilea număr. Pe următoarele n linii se află, pe fiecare, câte un șir de caractere format din litere mici ale alfabetului englez, reprezentând hobby-urile copiilor în ordinea în care sunt numerotați copiii.

Date de ieșire

Pe prima linie a fișierului de ieșire hobby1.out veți scrie numărul gr al grupurilor de copii. Pe următoarea linie veți afișa numărul grupurilor în care toți copiii au același hobby.

Restricţii şi precizări

  • 1 ≤ n ≤ 700.
  • 1 ≤ lungime_denumire_hobby ≤ 10.
  • 1 ≤ gr ≤ 400.
  • numărul de ordine al fiecărui copil apare o singură dată pe prima poziție a unei perechi.
  • un copil poate fi prietenul mai multor copii.
  • numărul maxim al hobby-urilor: 20.
  • La concurs s-au dat 10 puncte din oficiu, aici sunt date pe exemplu.

Exemplu

hobby.in
8
1 2
3 4
5 6
7 7
8 3
2 1
4 3
6 2
baschet
baschet
tenis
fotbal
baschet
baschet
muzica
tenis
hobby.out
3
2


Explicație

Avem 3 grupuri: 1: 1 2 5 6 2: 7 3: 3 4 8 Toți copiii din primul grup (cu numerele de ordine 1 2 5 6) au ca hobby baschetul, copilul 7 este singur, iar în al treilea grup hobby-urile diferă. Deci avem 2 grupuri în care copiii au același hobby.

Rezolvare

def form_groups(n, preferences, hobbies):
    groups = {}  # Dicționar pentru a înregistra grupurile

    for i in range(1, n+1):
        friend = preferences[i]
        hobby = hobbies[i]

        # Verificăm dacă prietenul preferat este deja într-un grup
        if friend in groups:
            # Adăugăm copilul curent în grupul prietenului său
            groups[friend].append(i)
            groups[i] = groups[friend]  # Actualizăm grupul pentru copilul curent
        else:
            # Creăm un nou grup pentru ei
            groups[i] = [i]

    return groups

def count_same_hobbies(groups, hobbies):
    same_hobby_groups = 0

    for group in groups.values():
        # Verificăm dacă toți copiii din grup au același hobby
        same_hobby = all(hobbies[child] == hobbies[group[0]] for child in group)
        if same_hobby:
            same_hobby_groups += 1

    return same_hobby_groups

def main():
    with open("hobby.in", "r") as fin:
        n = int(fin.readline())
        preferences = {}
        hobbies = {}

        for _ in range(n):
            child, friend = map(int, fin.readline().split())
            preferences[child] = friend

        for _ in range(n):
            hobbies[i] = fin.readline().strip()

    # Formăm grupurile
    groups = form_groups(n, preferences, hobbies)

    # Numărăm grupurile cu aceleași hobby-uri
    same_hobby_groups = count_same_hobbies(groups, hobbies)

    # Scriem rezultatul în fișierul de ieșire
    with open("hobby.out", "w") as fout:
        fout.write(str(len(groups)) + "\n")
        fout.write(str(same_hobby_groups) + "\n")

if __name__ == "__main__":
    main()