(待切)hdu 4096 大模拟(用map做爆栈了!!)

本文深入探讨了AI音视频处理领域的最新技术进展,包括视频分割、语义识别、自动驾驶等,同时展示了图像处理与AR特效在现实世界中的实际应用案例,从理论到实践全方位解析了这一领域的前沿发展。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Universal Question Answering System

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1229    Accepted Submission(s): 213


Problem Description
  Every student needs help from getting new knowledge by asking questions. Surveys are suggesting that some similar questions are repeated frequently. So it will be nice to develop an automatic question-answering system to answer these questions. Your algorithm should not have any prior knowledge, but it must be able to read sentences and remember the mentioned facts. Whenever the question is asked about such a fact, the system has to answer it properly.
 

Input
  The input consists of many dialogues.
  There is a single positive integer T on the first line of input. (T <= 500, but note that 95% of them are relatively small) It denotes the number of following dialogues. Each dialogue includes one or more lines. Each line contains one sentence: either a statement or a question. Statements end with a dot character (.) while questions end with a question mark (?). There is one extra line after each dialogue. That line ends with an exclamation mark (!). The definitions of the statements and questions will be discussed later.

Sentences can contain words, spaces and punctuation characters. All words contain only Latin letters and are case-sensitive. Unlike the normal English writing rules, the first letter of a sentence should keep lowercase unless the first word itself should begin with a capital letter. There are no extra spaces between words. No word will have more than 10 characters. There will be at most 1000 lines per dialogue.
Statements
Each statement has one of the following forms:

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.

noun_phrase and verb_phrase are both single word. The meanings of the four forms are:

A are B: If X is A, then X is B.
A can B: If X is A, then X has the ability to B.
everything which can A can B: If X has the ability to A, X has the ability to B.
everything which can A are B: If X has the ability to A, X is B.

Questions
Each question has one of the following forms:

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?


They are the question form of the statements.

In each test case, the number of different noun phrases will not exceed 100; the number of different verb phrases will not exceed 100.
 

Output
  For each test case, output two lines. The first line describes the test case number counting from 1, while the second line contains the same number of characters as the number of questions in this test case. Each character is either ‘Y’(denoting you can get that fact logically) or ‘M’(otherwise), without quotes.
 

Sample Input
  
  
1 flies can fly. flies are insects. everything which can fly are animals. are everything which can fly insects? are flies animals? can flies eat? everything which can fly can eat. can flies eat? Bye!
 

Sample Output
  
  
Case #1: MYMY
 

Source



题目大意:

有四种陈述句,有四种问句。每一句话的主体都是两个动词或者名词。

陈述句会给出逻辑推导蕴涵关系,而问句则要求回答问句中两个关键词是否存在逻辑推导关系(a是否是b的充分条件),若是输出Y,否则输出M;


解题思路:

用map将这些关键词对应起来。

因为提问的不一定会是直接的逻辑推导关系,可能两个关键词中间会隔着几层推导关系。

所以需要不断的一层一层找下去,如果遍历树的过程中找到了b则证明ab之间存在关系,否则就不存在。


下面是代码

不知道为什么在深搜的时候爆栈了,但是在本机上输入几百条语句都不会有问题。

#include <iostream>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <memory.h>
#include <string>
#include <vector>
#include <list>
#include <map>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <numeric>
#include <functional>
#define maxn 1000005

using namespace std;
int t;
bool flag;
map<string,string> M2,V2; //存名词,存动词

void solve(string &s,string &stds)
{
    if(s==stds){
        flag=true;
        return;
    }
    else {
        if(M2[s]!="")
            solve(M2[s],stds);
        if(V2[s]!="")
            solve(V2[s],stds);
    }
}

int main()
{
    int cas=1;
    //freopen("out.txt","w",stdout);
    scanf("%d",&t);
    getchar();
    while(t--){
        cout<<"Case #"<<cas++<<":\n";
        M2.clear();
        V2.clear();
        while(1){
            string tmps;
            cin>>tmps;
            if(tmps[tmps.length()-1]=='!') break;
            else if(tmps=="everything"){
                string s1,s2;
                while(tmps!="can") cin>>tmps;
                cin>>tmps;
                s1=tmps;
                while(tmps!="can"&&tmps!="are") cin>>tmps;
                if(tmps=="can"){
                    cin>>tmps;
                    s2=tmps;
                    s2.erase(s2.end()-1);
                    V2[s1]=s2;  //s1是s2的充分条件
                }
                else{
                    cin>>tmps;
                    s2=tmps;
                    s2.erase(s2.end()-1);
                    M2[s1]=s2;  //s1是s2的充分条件
                }
            }
            else if(tmps=="are"){
                string s1,s2;
                cin>>tmps;
                if(tmps=="everything"){
                    cin>>tmps;
                    cin>>tmps;
                    cin>>s1;
                    cin>>s2;
                    s2.erase(s2.end()-1);
                }
                else{
                    s1=tmps;
                    cin>>s2;
                    s2.erase(s2.end()-1);
                }
                flag=false;
                solve(s1,s2);
                if(flag) cout<<"Y";
                else cout<<"M";
            }
            else if(tmps=="can"){
                string s1,s2;
                cin>>tmps;
                if(tmps=="everything"){
                    cin>>tmps;
                    cin>>tmps;
                    cin>>s1;
                    cin>>s2;
                    s2.erase(s2.end()-1);
                }
                else{
                    s1=tmps;
                    cin>>s2;
                    s2.erase(s2.end()-1);
                }
                flag=false;
                solve(s1,s2);
                if(flag) cout<<"Y";
                else cout<<"M";
            }
            else{
                string s1,s2;
                s1=tmps;
                cin>>tmps;
                cin>>s2;
                s2.erase(s2.end()-1);
                if(tmps=="can") V2[s1]=s2;
                else M2[s1]=s2;
            }
        }
        cout<<"\n";
    }
    return 0;
}



下面是网上找的其他人的ac代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<map>
#define Maxn 210
using namespace std;
map<string,int> g;
map<string,int> ver;
int head[Maxn*2],vi[Maxn*2],e;
struct Edge{
    int u,v,next;
}edge[Maxn*Maxn*2];
void add(int u,int v){
    edge[e].u=u,edge[e].v=v,edge[e].next=head[u],head[u]=e++;
}
bool dfs(int u,int x)
{
    int i,v;
    vi[u]=1;
    if(u==x)
        return true;
    for(i=head[u];i!=-1;i=edge[i].next){
        v=edge[i].v;
        if(vi[v]) continue;
        if(dfs(v,x))
           return true;
    }
    return false;
}
int main()
{
    char str[101001],s1[Maxn],s2[Maxn],s3[Maxn],s4[Maxn],s5[Maxn],s6[Maxn];
    int cnt,num,i,j,t,Ca=0,u,v;
    scanf("%d",&t);
    getchar();
    while(t--){
        cnt=0;
        memset(vi,0,sizeof(vi));
        memset(head,-1,sizeof(head));
        e=0;
        g.clear();
        ver.clear();
        printf("Case #%d:\n",++Ca);
        while(cin.getline(str,2000,'\n')){
            int l=strlen(str);
            if(str[l-1]=='!'){
                printf("\n");
                break;
            }
            num=sscanf(str,"%s %s %s %s %s %s",s1,s2,s3,s4,s5,s6);
            if(num==3){
                l=strlen(s3);
                if(s3[l-1]=='.'){
                    s3[l-1]='\0';
                    if(s2[0]=='a'){
                        if(!g[s1]) g[s1]=++cnt;
                        if(!g[s3]) g[s3]=++cnt;
                        u=g[s1];
                        v=g[s3];
                    }else{
                        if(!g[s1]) g[s1]=++cnt;
                        if(!ver[s3]) ver[s3]=++cnt;
                        u=g[s1];
                        v=ver[s3];
                    }
                    add(u,v);
                }
                else{
                    s3[l-1]='\0';
                    if(!g[s2]) g[s2]=++cnt;
                    u=g[s2];
                    if(s1[0]=='a'){
                        if(!g[s3]) g[s3]=++cnt;
                        v=g[s3];
                    }
                    else{
                        if(!ver[s3]) ver[s3]=++cnt;
                        v=ver[s3];
                    }
                    memset(vi,0,sizeof(vi));
                    if(dfs(u,v)){
                        printf("Y");
                    }else {
                        printf("M");
                    }
                }
            }
            else{
                l=strlen(s6);
                if(s6[l-1]=='.'){
                    s6[l-1]='\0';
                    if(s5[0]=='a'){
                        if(!ver[s4]) ver[s4]=++cnt;
                        if(!g[s6]) g[s6]=++cnt;
                        u=ver[s4];
                        v=g[s6];
                    }else{
                        if(!ver[s4]) ver[s4]=++cnt;
                        if(!ver[s6]) ver[s6]=++cnt;
                        u=ver[s4];
                        v=ver[s6];
                    }
                    add(u,v);
                }
                else{
                    s6[l-1]='\0';
                    if(s1[0]=='c'){
                        if(!ver[s5]) ver[s5]=++cnt;
                        if(!ver[s6]) ver[s6]=++cnt;
                        u=ver[s5];
                        v=ver[s6];
                    }
                    else {
                        if(!ver[s5]) ver[s5]=++cnt;
                        if(!g[s6]) g[s6]=++cnt;
                        u=ver[s5];
                        v=g[s6];
                    }
                    memset(vi,0,sizeof(vi));
                    if(dfs(u,v)){
                        printf("Y");
                    }else {
                        printf("M");
                    }
                }
            }
        }
    }
    return 0;
}








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值