HDOJ 4096 / LA 5708 Universal Question Answering System

来源:互联网 发布:java单列模式 编辑:程序博客网 时间:2024/04/29 06:34

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=4096


题目大意:

给若干如下的论断:

noun_phrase are noun_phrase.
noun_phrase can verb_phrase.
everything which can verb_phrase can verb_phrase.
everything which can verb_phrase are noun_phrase.

再给出若干如下询问:

are noun_phrase noun_phrase?
can noun_phrase verb_phrase?
can everything which can verb_phrase verb_phrase?
are everything which can verb_phrase noun_phrase?

问此询问是否是正确的。


算法:

实际上就是一道输入输出题

把每个名词或者动词当作一个点,注意一个词可能既是名词又是动词。

然后如果一个句子中出现的第一个词是A,第二次是B,就连一条A->B的边。

判断时,如果一个句子中出现的第一个词是A,第二次是B,那么如果存在A->B的路径,结论就是正确的。

需要注意的trick是。可能出现"are A A?"和"can everything which can A A?"的情况,这种情况无论A是否出现过,结论都是正确的。

注:我的代码目前在uva可以AC但是在HDOJ还是TLE,等到我有时间会继续优化,抱歉。


代码如下:

#include<cstdio>#include<iostream>#include<cstdlib>#include<cstring>#include<climits>#include<cmath>#include<algorithm>#include<queue>#include<vector>#include<stack>#include<set>#include<map>#define INF 0x3f3f3f3fusing namespace std;const int maxn = 2010;const int maxm = 1010;string word[6];map <string, int> hash[2];bool vis[maxn << 1];char s[100000];int head[maxn << 1], nxt[maxm], to[maxm];int E = 0;void dfs(int u, int des){    vis[u] = true;    if(vis[des])    {        return;    }    for(int i = head[u]; i != -1; i = nxt[i])    {        int v = to[i];        if(! vis[v])        {            dfs(v, des);        }    }}void addedge(int x, int y){    to[E] = y;    nxt[E] = head[x];    head[x] = E ++;}inline int ffind(string ss, int flg){    map <string, int> :: iterator it;    it = hash[flg].find(ss);    int x = hash[flg].size();    if(it == hash[flg].end())    {        hash[flg][ss] = x;    }    else    {        x = it -> second;    }    return x + flg * maxn;}int main(){    int cas;    scanf("%d", &cas);    gets(s);    for(int T = 1; T <= cas; T ++)    {        printf("Case #%d:\n", T);        hash[0].clear();        hash[1].clear();        memset(head, -1, sizeof(head));        E = 0;        while(gets(s))        {            int cot = 0;            if(s[strlen(s) - 1] == '!')            {                puts("");                break;            }            string ss = "";            for(int i = 0; s[i]; i ++)            {                if(s[i] == ' ' || s[i] == '.' || s[i] == '?')                {                    word[cot ++] = ss;                    ss = "";                }                else                {                    ss += s[i];                }            }            int x, y;            if(s[strlen(s) - 1] == '.')            {                if(cot == 3)                {                    if(word[1][0] == 'a')                    {                        x = ffind(word[0], 0);                        y = ffind(word[2], 0);                    }                    else                    {                        x = ffind(word[0], 0);                        y = ffind(word[2], 1);                    }                }                else                {                    if(word[4][0] == 'c')                    {                        x = ffind(word[3], 1);                        y = ffind(word[5], 1);                    }                    else                    {                        x = ffind(word[3], 1);                        y = ffind(word[5], 0);                    }                }                addedge(x, y);            }            else            {                if(cot == 3)                {                    if(word[0][0] == 'a')                    {                        x = ffind(word[1], 0);                        y = ffind(word[2], 0);                    }                    else                    {                        x = ffind(word[1], 0);                        y = ffind(word[2], 1);                    }                }                else                {                    if(word[0][0] == 'c')                    {                        x = ffind(word[4], 1);                        y = ffind(word[5], 1);                    }                    else                    {                        x = ffind(word[4], 1);                        y = ffind(word[5], 0);                    }                }                memset(vis, 0, sizeof(vis));                dfs(x, y);                if(vis[y])                {                    putchar('Y');                }                else                {                    putchar('M');                }            }        }    }    return 0;}



原创粉丝点击