Cod sursa(job #2590418)

Utilizator SirbuSirbu Ioan Sirbu Data 27 martie 2020 21:24:56
Problema NFA Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.65 kb
#include <bits/stdc++.h>
#include <queue>
#include <vector>
#include <unordered_map>
#include <cstring>
#define NMAX 10000

using namespace std;

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

int v[NMAX][NMAX], k, m, n, q0, l, x;
unordered_map<char, vector<int>> M[NMAX];
queue <int> Q1,Q2;
char s[302];
bool F[NMAX];

bool evaluate(char s[], int cuv){

    int lung = strlen(s);
    Q1.push(q0);
    v[cuv][q0] = 1;
    for(int i = 0; i < lung; i++){
        int j = i+1;
        if(j%2){
            if(Q1.empty())
                return false; // daca am ramas fara stari,cuvantul este respins(nu s-a putut ajunge in nicio stare)
            while(!Q1.empty())
            {
                int x = Q1.front();
                Q1.pop();
                //Q2.push(x); punem tot ce este in Q1 in Q2(putem ajunge din starea q in starea q fara litere)
                for(int y : M[x][s[i]])
                    if(v[cuv][y] != j)
                    {
                        v[cuv][y] = j;
                        Q2.push(y); //punem toate starile in care punem ajunge cu $ si le vizitam
                    }
            }
        }
        else {
            if (Q2.empty())
                return false;
            while(!Q2.empty())
            {
                int x = Q2.front();
                Q2.pop();
                for(int y : M[x][s[i]])
                    if(v[cuv][y] != j)
                    {
                        v[cuv][y] = j;
                        Q1.push(y); //folosind caracterul curent,punem in Q1 toate starile in care putem ajunge si le vizitam pentru pasul urmator
                    }
            }
        }
    }
    if((lung+1)%2)
        while(!Q1.empty()){ // dupa ce am terminat cuvantul,inca putem folosi $,deci mai trecem odata prin Q1
            int x = Q1.front();
            Q1.pop();
            //Q2.push(x);
            if (F[x])
                return true;
        }
    else
        while(!Q2.empty()) // verificam daca vreuna din starile cu care am terminat este stare finala
        {
            int x = Q2.front();
            Q2.pop();
            if (F[x])
                return true;
        }
    return false;
}

int main (){

    fin >> n >> m >> k;
    fin >> q0;
    for(int i = 0; i < k; i++){
        fin >> x;
        F[x] = 1;
    }
    for(int i = 1; i <= m; i++){
        int x, y;
        char a;
        fin >> x >> y >> a;
        M[x][a].push_back(y);
    }
    fin >> l;
    for (int i = 1; i <= l; ++i){
        fin >> s;
        if(evaluate(s,i))
            fout << 1 << '\n';
        else
            fout << 0 << '\n';
    }
}