Rezolvare completă PbInfo #1425 Ghirlande

Deoarece vin sărbătorile, elevii de la Liceul de informatică s-au gândit să decoreze laboratorul P1 cu ghirlande legate între ele. Ei au cumpărat N ghirlande numerotate de la 1 la N și vor să le lege împreună apoi să orneze laboratorul. Fiecare ghirlandă are doua culori distribuite astfel încât capetele să aibă culori diferite. Culorile sunt codificate prin numere naturale. Decoraţiunile cumpărate au N-1 culori care apar exact de două ori şi 2 culori care apar doar o singură dată. Pentru a face munca mai distractivă ei s-au gândit că, la legarea a două ghirlande, să unească două capete de aceeaşi culoare.

Cerința

1) Pentru cerinţa 1 copiii vor să afle suma codurilor culorilor aflate la cele două capete ale lanţului format prin legarea ghirlandelor cumpărate, respectând regulile de îmbinare de mai sus.
2) Pentru cerinţa 2 ajutaţi-i să lege ghirlandele pentru a decora laboratorul P1 respectând regulile menţionate. Trebuie sa afisati numerele de ordine ale ghirlandelor în ordinea în care vor fi legate. La cele doua capete se vor afla
cele doua ghirlande care conțin o culoare ce apare o singura data. Dintre acestea prima va fi cea care are codul culorii mai mic

Date de intrare

Fișierul de intrare ghirlande.in conține pe prima linie numărul T. Dacă T este 1 se va rezolva cerinţa 1, iar dacă T este 2 se va rezolva cerinţa 2. Pe linia a doua apare numărul de ghirlande N. Pe următoarele N linii se găsesc câte 2 numere ai bi cu următoarea semnificaţie: ghirlanda cu numărul i (1≤i≤N) are culoarea ai până la jumătate şi culoarea
bi de la jumătate.

Date de ieșire

Fișierul de ieșire ghirlande.out:

  • dacă T=1 atunci va conţine o singură linie unde se va afişa suma cerută
  • dacă T=2 atunci va conţine o singură linie unde vor fi afişate N numere cu valori între 1 şi N, reprezentând numerele de ordine ale ghirlandelor, din fişierul de intrare. Aceste numere reprezintă ordinea în care se leagă ghirlandele între ele.

Restricții și precizări

  • 2 ≤ N ≤ 900.000
  • 1 ≤ ai, bi ≤ 2*106 (pentru 1≤i≤N)

Exemplul 1

ghirlande.in

1
3
400 3
5 10
3 5

ghirlande.out

410

Explicație

Codurile celor două capete sunt: 400 şi 10.

Exemplul 2

ghirlande.in

2
3
400 3
5 10
3 5

ghirlande.out

2 3 1

Exemplul 2

ghirlande.in

2
5
3 5
6 12
5 12
7 8
6 8

ghirlande.out

1 3 2 5 4

Cum e corect?

cout < "As la info"; cout << "As la info"; cout >> "As la info";

Felicitări! Poți mai mult?

Avem sute de probleme pentru tine, fiecare cu explicații ușor de înțeles.

Greșit, dar nu-i bai!

Antrenează-te cu sutele de probleme pe care ți le-am pregătit. Îți explicăm fiecare problemă în parte.

Rezolvare

Iată rezolvarea de 100 de puncte pentru problema Ghirlande:

#include <fstream>
#define Nmax 2000000
using namespace std;

ifstream fin("ghirlande.in");
ofstream fout("ghirlande.out");

long cerinta, i , n, first, last, x, y, ap[2000005], ant;
long a[2000005],b[2000005],poza[2000005],pozb[2000005];
int main()
{
    //citire
    fin>>cerinta;
    fin>>n;
    //punem toate ghirlandele in doi vectori de corespondenta (a si b) cu semnificatia: o ghirlanda care are un capat de culoare x are celalalt capat de culaore a[x] si cealalta ghirlanda care are un capat de culaore x are celalalt capat de culoare b[x]. Daca o culoare nu apare decat la o singura ghirlanda(adica aceasta este capatul lantului) b[x] va ramane 0.
    //in poza si pozb retinem pe ce pozitie a fisierului de intrare a aparut ghirlanda de culoare x
    for (i=1;i<=n;i++)
    {
        fin>>x>>y;
        if (a[x]==0)
        {
            a[x]=y;
            poza[x]=i;
        }
        else
        {
            b[x]=y;
            pozb[x]=i;
        }
        if (a[y]==0)
        {
            a[y]=x;
            poza[y]=i;
        }
        else
        {
            b[y]=x;
            pozb[y]=i;
        }
    }
    //rezolvam cerinta 1
    //parcurgem vectorul de corespondenta si cautam pozitiile care au o valoare diferita de 0 doar pe pozitia a[x].
    if (cerinta==1)
    {
        for (i=1;i<=Nmax;i++)
            if (a[i]!=0 && b[i]==0)
            {
                last=first;
                first=i;
            }
        fout<<first+last;
    }
    else
    {
        //pentru cerinta 2 cautam un capat la fel ca la cerinta 1 si parcurgem vectorul de corespondenta dupa cum urmeaza:
        //retinem de unde am venit ca sa nu ne intoarcem
        for (i=1;i<=Nmax;i++)
            if (a[i]!=0 && b[i]==0)
            {
                last=first;
                first=i;
            }
        if (first>last)
            first=last;
        fout<<poza[first]<<;
        ant=first;
        first=a[first];
        while (b[first]!=0)
        {
            if (a[first]==ant)
            {
                ant=first;
                fout<<pozb[first]<<;
                first=b[first];
            }
            else
            {
                ant=first;
                fout<<poza[first]<<;
                first=a[first];
            }
        }
    }

    return 0;
}

Atenție

Enunțurile afișate pe această pagină aparțin exclusiv site-ului PbInfo. Astfel, pentru ștergerea conținutului, puteți să ne contactați la adresa Adresa de email.

Rezolvarea problemei #1425 Ghirlande

Pe această pagină găsești rezolvarea de 100 de puncte pentru problema #1425 Ghirlande de pe PbInfo.ro. Atenție: nu încurajăm copiatul codului! Totuși, credem cu tărie că analizarea unei soluții corecte este o metodă foarte ușoară de a învăța informatică, astfel că oferim sursele pentru peste 1500 de probleme de pe platforma PbInfo.ro.

Pentru rezolvări PbInfo de la peste 1500 de probleme, vă invităm să intrați pe site-ul nostru!