Cod sursa(job #2588536)

Utilizator AndreiStanescuAlloys Nokito AndreiStanescu Data 24 martie 2020 21:47:19
Problema NFA Scor 80
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 8.42 kb
//AFN (si AFD) -optimizat
/*#include<bits/stdc++.h>
#define N 1000
using namespace std;
int n,m,start,nre;

unordered_set<int> sfarsit;
char s[N];

typedef unordered_multimap<char, int>:: iterator umit;

vector<  unordered_multimap< char, int  > > citire()
{
    ifstream fin("AFD.txt");
    //ifstream fin("AFN.txt");
    int x,y,i;
    char c;
    fin>>n;
    fin>>m;
    //some garbage value in order to be initialized this vector
    vector<  unordered_multimap< char, int  > > G(n,{ {'z',-1} });
    for(i=0;i<m;i++)
    {
        fin>>x>>y>>c;
        G[x].insert({c,y});
    }
    fin>>start;
    fin>>nre;
    for(i=0;i<nre;i++)
    {
        fin>>x;
        sfarsit.insert(x);
    }
    cin>>s;
    fin.close();
    //cout<<G[3].count('a');
    return G;
}



bool accepta(vector<  unordered_multimap< char, int  > > G)
{
    //cout<<G[1].count('b');
    int inc,i,l,r,index;
    int q[N]={start};
    l=0;
    r=1;
    for(i=0;i<strlen(s);i++)
    {
        bool gasit=false;
        int k=r;
        for(index=l;index<k;index++)
        {
            inc=q[index];
            //cout<<inc<<' ';
            pair<umit,umit> it=G[inc].equal_range(s[i]);
            umit it1=it.first;
            umit it2=it.second;
            while(it1!=it2)
            {
                if(it1->second!=-1)  //din cauza valorii de initializare
                {q[r++]=it1->second;
                gasit=true;
                it1++;
                }
            }
        }
        if(gasit==false)
               return 0;
        l=k;

    }
    for(index=l;index<r;index++)
    {
        inc=q[index];
        if(sfarsit.count(inc))
            return 1;
    }

}


int main()
{
    //vector<  unordered_multimap< char, int  > > G=citire();
    //cout<<G[3].count('a');
    cout<<accepta(citire());
}*/

//determinist
/*#include<bits/stdc++.h>
#define N 1000
using namespace std;

int n,m,start,nre;
vector< pair< int, char > > G[N];
set<int> sfarsit;
char s[N];

void citire()
{
    ifstream fin("AFD.txt");
    int x,y,i;
    char c;
    fin>>n;
    fin>>m;
    for(i=0;i<m;i++)
    {
        fin>>x>>y>>c;
        G[x].push_back(make_pair(y,c));
    }
    fin>>start;
    fin>>nre;
    for(i=0;i<nre;i++)
    {
        fin>>x;
        sfarsit.insert(x);
    }
    fin>>s;
    fin.close();
}



bool accepta()
{
    int inc=start,i;
    for(i=0;i<strlen(s);i++)
    {
        bool gasit=false;
        for(auto &it:G[inc] )
        {
            if(it.second==s[i])
            {
                inc=it.first;
                gasit=true;
            }
        }
        if(gasit==false)
               return 0;

    }
    if(sfarsit.count(inc))
        return 1;

}


int main()
{
    citire();
    cout<<accepta();
}*/

//nedeterminist-neoptim
/*#include<bits/stdc++.h>
#define N 1000
using namespace std;

int n,m,start,nre;
vector< pair< int, char > > G[N];
set<int> sfarsit;
char s[N];

void citire()
{
    ifstream fin("AFN.txt");
    int x,y,i;
    char c;
    fin>>n;
    fin>>m;
    for(i=0;i<m;i++)
    {
        fin>>x>>y>>c;
        G[x].push_back(make_pair(y,c));
    }
    fin>>start;
    fin>>nre;
    for(i=0;i<nre;i++)
    {
        fin>>x;
        sfarsit.insert(x);
    }
    cin>>s;
    fin.close();
}



bool accepta()
{
    int inc,i,l,r,index;
    int q[N]={start};
    l=0;
    r=1;
    for(i=0;i<strlen(s);i++)
    {
        bool gasit=false;
        int k=r;
        for(index=l;index<k;index++)
        {
            inc=q[index];
        for(auto &it:G[inc] )
        {
            if(it.second==s[i])
            {
                q[r++]=it.first;
                gasit=true;
            }
        }
        }
        if(gasit==false)
               return 0;
        l=k;

    }
    for(index=l;index<r;index++)
    {
        inc=q[index];
        if(sfarsit.count(inc))
            return 1;
    }

}


int main()
{
    citire();
    cout<<accepta();
}*/


//cele mai mici 100 de cuvinte
/*#include<bits/stdc++.h>
#define N 100
#define M 100
using namespace std;

int n,m,start,nre;
vector< pair< int, char > > G[N];
unordered_set<int> sfarsit;
vector<string>ans;
char s[N];

void citire()
{
    ifstream fin("AFN.txt");
    int x,y,i;
    char c;
    fin>>n;
    fin>>m;
    for(i=0;i<m;i++)
    {
        fin>>x>>y>>c;
        G[x].push_back(make_pair(y,c));
    }
    fin>>start;
    fin>>nre;
    for(i=0;i<nre;i++)
    {
        fin>>x;
        sfarsit.insert(x);
    }
    fin>>s;
    fin.close();
}

struct mat{
    int node;
    string cuv;
}q[N*M];

void distante()
{
    int inc,i,l,r,index,nod;
    q[0].node=start;
    q[0].cuv="";
    l=0;
    r=1;
    while(l<r)
    {
		nod = q[l].node;
		//cout<<nod<<' ';
		for (auto &it : G[nod])
		{
			q[r].node = it.first;
			q[r].cuv=q[l].cuv+it.second;
            if(sfarsit.count(it.first))
                {
                    ans.push_back(q[r].cuv);
                    cout<<ans.size()<<' ';
                    if(ans.size()>=N) goto afisare;
                //cout<<q[r].cuv<<'\n';
                }
            ++r;

		}
		++l;
    }
afisare:
    for(i=0;i<ans.size();i++)
        cout<<ans[i]<<'\n';

}




int main()
{
    citire();
    distante();
}*/

//nfa-infoarena (cu multimap)
#include<bits/stdc++.h>
#define N 153
#define Nmax 303
using namespace std;
int n,m,q,start,nre;

unordered_set<int> sfarsit;

typedef unordered_multimap<char, int>:: iterator umit;

vector< pair<int,char> > mat[Nmax];

/*bool accepta(vector<  unordered_multimap< char, int  > >& G,string s)
{
    int inc,i,l,r,index;
    int q[N*Nmax]={start};
    queue<int> q1;
    q1.push(start);
    l=0;
    r=1;
    for(i=0;i<s.size();i++)
    {
        bool gasit=false;
        int k=r;
        for(index=l;index<k;index++)
        {
            //inc=q[index];
            inc=q1.front();
            q1.pop();
            //cout<<inc<<' ';
            pair<umit,umit> it=G[inc].equal_range(s[i]);
            umit it1=it.first;
            umit it2=it.second;
            while(it1!=it2)
            {
                if(it1->second!=-1)  //din cauza valorii de initializare
                {//q[r++]=it1->second;
                    q1.push(it1->second);
                    r++;
                    gasit=true;
                    it1++;
                }
            }

        }
        if(gasit==false)
               return 0;
        l=k;

    }
    for(index=l;index<r;index++)
    {
        //inc=q[index];
        inc=q1.front();
        q1.pop();
        if(sfarsit.count(inc))
            return 1;
    }
    return 0;

}*/

bool raspuns,viz[Nmax][N];

void dfs(int x,int i,string s)
{
    if(raspuns)
        return;
    if(i==s.size())
    {
        if(sfarsit.count(x))
            raspuns=1;
        return;
    }
    viz[x][i]=1;
    bool ceva=false;
    for(int index=0;index<mat[x].size();++index)
    {
        if((mat[x][index].second)==s[i])
        {
            int curr=mat[x][index].first;
            ceva=true;
            //daca am mai ajuns in acest nod la pozitia actuala nu are rost sa mai verific inca o data
            if(!viz[curr][i+1])
                dfs(curr,i+1,s);
        }
    }
    if(ceva==false)
    {
        return;
    }

}

void citire()
{
    ifstream fin("nfa.in");
    ofstream fout("nfa.out");
    int x,y,i;
    string s;
    char c;
    fin>>n;
    fin>>m;
    fin>>nre;
    fin>>start;
    for(i=0;i<nre;i++)
    {
        fin>>x;
        sfarsit.insert(x);
    }
    //some garbage value in order to be initialized this vector
    //vector<  unordered_multimap< char, int  > > G(Nmax+1);
    for(i=0;i<m;i++)
    {
        fin>>x>>y>>c;
        //G[x].insert({c,y});
        mat[x].push_back({y,c});
    }
    fin>>q;
    for(i=0;i<q;i++)
    {
        fin>>s;
        //fout<<accepta(G,s)<<'\n';
        raspuns=0;
        //memset(viz,0,sizeof(viz));
        for(int k=0;k<=n;k++)
            for(int l=0;l<=s.size()+1;l++)
            viz[k][l]=0;
        dfs(start,0,s);
        fout<<raspuns<<'\n';
    }
    fin.close();
    fout.close();
    //cout<<G[3].count('a');
    //return G;
}



int main()
{
    //vector<  unordered_multimap< char, int  > > G=citire();
    //cout<<G[3].count('a');
    citire();
}