现在的位置: 首页 > 综合 > 正文

HDOJ 4096 / LA 5708 Universal Question Answering System

2014年10月10日 ⁄ 综合 ⁄ 共 2275字 ⁄ 字号 评论关闭

题目链接:

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 0x3f3f3f3f
using 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;
}

【上篇】
【下篇】

抱歉!评论已关闭.