Cod sursa(job #3331017)

Utilizator maxtraAlex Deonise maxtra Data 23 decembrie 2025 19:32:46
Problema Aprindere Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.56 kb
// /*
// enunt:
// ai N camere in linie: 0, 1, .., N-1, fiecare are un bec (0 - stins, 1 - aprins)
// exista M intrerupatoare (cel putin 1 in fiecare camera). un intrerupator aflat in camera C:
// - intotdeauna schimba starea becului din camera C;
// - poate schimba si becuri din camere cu index mai mare decat C;
// - actionarea lui costa T timp;

// schimbarea starii: toggle intre 0 si 1

// scop: sa ajungi ca in toate camerele sa fie becul aprins (1) cu timp total minim

// solutie:
// de ce nu merge un algoritm de la stanga-dreapta
// pentru o camera i:
// - intrerupatoarele din camere mai mari (> i) NU au voie sa ii modifice becul (un intrerupator 
// modifica becul din camera sa si eventual dupa ea)
// - deci dupa ce ai trecut de i, nu mai poti modifica becul din i

// asta face decizia ca la camera i sa fie fortata:
// - daca atunci cand ajungi la i, becul este 0, trebuie doar sa apesi intrerupatorul din i ca sa l aprinzi
// - daca e 1, nu l apesi (altfel l ai stinge si nu mai ai cum sa l reaprinzi mai tarziu)

// prin urmare, solutia minima este practic deterministica: parcurgi camerele in ordine si apesi exact unde este nevoie
// (Alg de tip Greedy)

// algoritm:
// citesti n si m
// citesc starea initiala a becurilor in a[0..n-1]
// citesti toate intrerupatoarele in vectorul v[], avand:
// - poz = camera unde este intrerupatorul
// - t = timpul de apasare
// - nr = camera modificata
// - c[] = lista camerelor modificate (include mereu poz)
// parcurgerea intrerupatoarelor si pentru fiecare:
// - daca in camera lui (a[poz]) becul este stins, apasa
// - daca face toggle pentru toate camerele din lista c[]
// - adauga timpul t in sum
// scrie sum
// */
// #include <bits/stdc++.h>
// using namespace std;

// // Pentru fiecare cameră putem avea cel mult un întrerupător.
// struct SwitchInfo {
//     bool exists = false;   // există întrerupător în camera asta?
//     int t = 0;             // timpul de apăsare
//     int nr = 0;            // câte camere modifică
//     int c[105];            // lista camerelor modificate (nr <= 100)
// };

// int main() {
//     ifstream fin("aprindere.in");
//     ofstream fout("aprindere.out");

//     int n, m;
//     fin >> n >> m;

//     // a[i] = starea becului din camera i (0/1)
//     int a[1001];
//     for (int i = 0; i < n; i++) fin >> a[i];

//     // sw[C] = întrerupătorul din camera C (dacă există)
//     SwitchInfo sw[1001];

//     for (int k = 0; k < m; k++) {
//         int C, T, NRC;
//         fin >> C >> T >> NRC;

//         sw[C].exists = true;
//         sw[C].t = T;
//         sw[C].nr = NRC;

//         for (int j = 0; j < NRC; j++) {
//             fin >> sw[C].c[j];
//         }
//     }

//     long long sum = 0;

//     // Parcurgem camerele în ordine (0..N-1).
//     // IMPORTANT: după ce trecem de i, nimic din dreapta nu mai poate modifica camera i.
//     for (int i = 0; i < n; i++) {
//         if (!sw[i].exists) {
//             // În teste există mereu soluție, deci dacă i e 0 acum, înseamnă că a fost
//             // aprinsă din întrerupătoare anterioare. (Sau era deja 1.)
//             continue;
//         }

//         // Dacă becul din camera i este stins când ajungem aici, trebuie apăsat.
//         if (a[i] == 0) {
//             // Apăsăm întrerupătorul: toggle pe toate camerele din lista lui.
//             for (int j = 0; j < sw[i].nr; j++) {
//                 int room = sw[i].c[j];
//                 a[room] ^= 1;  // toggle: 0->1, 1->0
//             }
//             sum += sw[i].t;
//         }
//         // Dacă a[i] e deja 1, nu apăsăm (altfel l-am stinge și nu îl mai putem repara).
//     }

//     fout << sum;
//     return 0;
// }
#include <fstream>
using namespace std;

struct intrerupator
{
    int timp;
    int nr;
    int cam[100];
};

int main()
{
    ifstream fin("aprindere.in");
    ofstream fout("aprindere.out");

    int N, M;
    fin >> N >> M;

    int a[1000];
    for (int i = 0; i < N; i++)
        fin >> a[i];

    intrerupator intr[1000];
    bool exista[1000] = {0};

    for (int i = 0; i < M; i++)
    {
        int C;
        fin >> C >> intr[C].timp >> intr[C].nr;
        exista[C] = true;

        for (int j = 0; j < intr[C].nr; j++)
            fin >> intr[C].cam[j];
    }

    int f[1000] = {0};
    int sum = 0;

    for (int i = 0; i < N; i++)
    {
        int stare = (a[i] + f[i]) % 2;

        if (stare == 0)
        {
            sum += intr[i].timp;

            for (int j = 0; j < intr[i].nr; j++)
                f[ intr[i].cam[j] ]++;
        }
    }

    fout << sum << endl;

    fin.close();
    fout.close();
    return 0;
}