Cod sursa(job #3264908)

Utilizator Luijika_programatorulBursuc Luigi Luijika_programatorul Data 25 decembrie 2024 16:00:58
Problema Lista lui Andrei Scor 45
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.69 kb
#include <bits/stdc++.h>
std::ifstream fin("nrcuv.in");
std::ofstream fout("nrcuv.out");


/**

Determinati cate cuvinte de lungime N se pot forma folosind doar litere mici ale alfabetului englez astfel incat
oricare doua litere care formeaza o pereche in lista lui Andrei sa nu se afle pe pozitii vecine.

2 7
a a
a b
b c
c d
c f
b a
c f

dp(i,ch) : # de moduri de a construi un string cu lungimea i , si ultimul caracter sa fie ch.

rasp este dp(n,'a') + dp(n,'b') + ... dp(n,'z');

dp(i,ch) =

dp(i - 1 , x0) + dp(i-1 ,x1) + dp(i-1 , x2) + ... dp(i-1, xn)

unde x reprezinta multimea caracterelor compatibile cu ch

*/
#define int long long
const int mod = 104659;

std::unordered_map<char,int> dp[1005];
std::vector<char> x[26];
int n,m;
bool fr[26][26];

void afis_ans(){
    int S=0;
    for(char i = 'a'; i<= 'z' ; ++i){
        S = (S + dp[n][i]) % mod;
    }
    fout << S;
}

void read_input_and_precalc(){
    fin >> n >> m;
    for(int i=0;i<26;++i){
        for(int j=0;j<26;++j)fr[i][j] = 1;
    }
    while(m--){
        char a,b;
        fin >> a >> b;
        fr[a - 'a'][b - 'a'] = 0;
        fr[b-'a'][a-'a'] = 0;
    }

    for(int i=0;i<26;++i){
        for(int j=0;j<26;++j){
            if(fr[i][j]){
                x[i].push_back((char)(j + 'a'));
            }
        }
    }


}



int32_t main(){
    read_input_and_precalc();

    for(char i = 'a';  i<= 'z' ; ++i){
        dp[1][i] = 1;
    }

    for(int i=2;i<=n;++i){
        for(int ch = 'a' ; ch <= 'z' ; ++ch){
            for(auto f : x[ch - 'a']){
                dp[i][ch] += dp[i-1][f];
            }
        }
    }


    afis_ans();
    return 0;
}