Cod sursa(job #3322569)

Utilizator RaresGeoGeorge Rares RaresGeo Data 14 noiembrie 2025 19:44:13
Problema Lista lui Andrei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.73 kb
#include <iostream>
#include <fstream>
using namespace std;

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

const int mod = 104659;

int n, m, fr[30][30], a[1005][30];
/*
fr - reprezinta matricea de interdictii
fr[i][j] = 1 daca perechea (i, j) neste interzisa (nu pot avea i urmat de j)
fr[l1 - 'a'][l2 - 'a'] = 1; ->
l1 - 'a' -> convertetsc litera 'a', .. 'z' in index 0, .., 25
marchez sicmetric (adica daca a,b este interzis, si b, a este interzis)


a[i][j] - numarul de cuvinte valide de lungime i+1 care se termina cu litera j
j este indicele literei (0 = 'a', 1 = 'b', ..)
de ce lungime i+1 si nu i?
for (int i = 0; i < 26; i++) {
    a[0][i] = 1;
}
deci a[0][i] reprezinta cuvinte de lungime 1 (un singur char), nu zero.
de aceea la final o sa folosim a[n-1][..] pentru lungimea n
pentru lungime 1, poti avea orice litera
nu exista vecini, deci nu se aplica nicio interdictie
deci pentru fiecare litera i, exista exact 1 cuvant de lungime 1 care se termina
cu litera i

for(int i = 1; i <= n; i++) {
    for (int j = 0; j < 26; j++) {
        for (int k = 0; k < 26; k++) {
            if (fr[j][k] != 1 && fr[k][j] != 1) {
                a[i][j] = (a[i][j] + a[i-1][k]) % mod;
            }
        }
    }
}
i - lungimea curenta minus 1 (pentru ca a[i] - cuvinte de lungime i+1)
i = 1 -> lungime 2
i = 2 -> lungime 3
...
j - indexul ultimei litere din cuvantul nou (de lungime i+1)
k - indexul penultimei litere (ultima litera a cuvintelor de  lungime i)

ca sa formez un cuvant de lungime i+1 care se termina in litera j, iau toate cuvintele
de lungime i care se termina in litera k, pentru toate k care nu formeaza o pereche
interzisa cu j

unde se afla raspunsul?
in a[n-1][j]
de ce?
long long sum = 0;
for (int i = 0; i < 26; i++) {
    sum = (a[n - 1][i] + sum) % mod;
}

a[0][*] -> de lungime 1
a[1][*] -> de lungime 2
..
a[n-1][*] -> de lungime n
raspunsul total = suma tuturor cuvintelor de lungime n care se termina cu orice litera
*/
int main()
{
    fin >> n >> m;

    for (int i = 0; i < m; i++)
    {
        char l1, l2;
        fin >> l1 >> l2;

        fr[l1 - 'a'][l2 - 'a'] = 1;
        fr[l2 - 'a'][l1 - 'a'] = 1;
    }

    for (int i = 0; i < 26; i++)
    {
        a[0][i] = 1;
    }

    for (int i = 1; i < n; i++)
    {
        for (int j = 0; j < 26; j++)
        {
            for (int k = 0; k < 26; k++)
            {
                if (fr[j][k] != 1 && fr[k][j] != 1)
                {
                    a[i][j] = (a[i][j] + a[i - 1][k]) % mod;
                }
            }
        }
    }

    long long sum = 0;
    for (int i = 0; i < 26; i++)
    {
        sum = (sum + a[n - 1][i]) % mod;
    }

    fout << sum;
    return 0;
}