Pagini recente » Cod sursa (job #2711287) | Cod sursa (job #3319178) | Cod sursa (job #3346053) | Cod sursa (job #2435154) | Cod sursa (job #3322569)
#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;
}