题目大意:给出一些陈述句描述名词与名词或动词之间的关系,再给出一些疑问句询问名词与名词或动词之间的关系是否存在。
解题思路:自己写了一个版本,提交了20多次都没有找到WA在哪里?只好参照了这篇博客的写法,然后就1A了,表示很无语呀!该题主要是两个方面的处理,对字符串的处理上,如何把关键词抠出来。然后对这些关键词进行建图处理,再对每一次询问的时候进行搜索两个关键词之间是否存在路径,如果有则说明关系存在,反之亦然。详见code。
题目来源:http://acm.hdu.edu.cn/showproblem.php?pid=4096
code:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <map>
using namespace std;
const int MAXN = 200+10;
const int M = 1e5+100;
int t,cas,cnt,u,v;
map<string,int> nou;
map<string,int> ver;
int head[MAXN*2],vis[MAXN*2],eid;
char str[M],s1[MAXN],s2[MAXN],s3[MAXN],s4[MAXN],s5[MAXN],s6[MAXN];
struct Edge{
int v,next;
}e[MAXN*MAXN*2];
void addedge(int u,int v){ //建图
e[eid].v=v;
e[eid].next=head[u];
head[u]=eid++;
}
bool dfs(int u,int v){ //路径搜索
vis[u]=1;
if(u==v) return true;
for(int i=head[u];i!=-1;i=e[i].next){
if(!vis[e[i].v])
if(dfs(e[i].v,v))
return true;
}
return false;
}
int main(){
//freopen("input.txt","r",stdin);
cas=0;
scanf("%d",&t);
getchar();
while(t--){
printf("Case #%d:\n",++cas);
cnt=0;eid=0;
nou.clear();ver.clear();
memset(head,-1,sizeof(head));
while(gets(str)){//cin.getline(str,2000,'\n'),这里使用gets的时间更快
int len=strlen(str);
if(str[len-1]=='!'){ //结束判断
printf("\n");
break;
}
int num=sscanf(str,"%s %s %s %s %s %s",s1,s2,s3,s4,s5,s6); //接收每一个单词
if(num==3){ //如果句子长度为3
len=strlen(s3);
if(s3[len-1]=='.'){ //如果为陈述句
s3[len-1]='\0';
if(s2[0]=='a'){ //关键词为are,表示关键词为名词
if(!nou[s1]) nou[s1]=++cnt;
if(!nou[s3]) nou[s3]=++cnt;
u=nou[s1];
v=nou[s3];
}
else{ //关键词为can,表示关键词为名词+动词
if(!nou[s1]) nou[s1]=++cnt;
if(!ver[s3]) ver[s3]=++cnt;
u=nou[s1];
v=ver[s3];
}
addedge(u,v); //增加有向边
}
else{ //如果为疑问句
s3[len-1]='\0';
if(s1[0]=='a'){ //关键词为are,表示关键词为名词
if(!nou[s2]) nou[s2]=++cnt;
if(!nou[s3]) nou[s3]=++cnt;
u=nou[s2];
v=nou[s3];
}
else{ //关键词为can,表示关键词为名词+动词
if(!nou[s2]) nou[s2]=++cnt;
if(!ver[s3]) ver[s3]=++cnt;
u=nou[s2];
v=ver[s3];
}
memset(vis,0,sizeof(vis)); //初始化访问数组
if(dfs(u,v)) printf("Y"); //进行路径搜索
else printf("M");
}
}
else{ //如果句子长度为6,与长度为3的判断方法一致
len=strlen(s6);
if(s6[len-1]=='.'){
s6[len-1]='\0';
if(s5[0]=='a'){
if(!ver[s4]) ver[s4]=++cnt;
if(!nou[s6]) nou[s6]=++cnt;
u=ver[s4];
v=nou[s6];
}
else{
if(!ver[s4]) ver[s4]=++cnt;
if(!ver[s6]) ver[s6]=++cnt;
u=ver[s4];
v=ver[s6];
}
addedge(u,v);
}
else{
s6[len-1]='\0';
if(s1[0]=='a'){
if(!ver[s5]) ver[s5]=++cnt;
if(!nou[s6]) nou[s6]=++cnt;
u=ver[s5];
v=nou[s6];
}
else{
if(!ver[s5]) ver[s5]=++cnt;
if(!ver[s6]) ver[s6]=++cnt;
u=ver[s5];
v=ver[s6];
}
memset(vis,0,sizeof(vis));
if(dfs(u,v)) printf("Y");
else printf("M");
}
}
}
}
return 0;
}