题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4096
神坑一:名词和动词可能拼写相同,所以要区分一下词性
神坑二(猜想):提问中可能有问一些诸如“are Z Z?” 然后在原文中却压根没提到Z的...
个人的具体做法:
通过map来给每一个读进来的单词一个数字编号
词性的区分通过在单词前面加前缀v和n来实现【网上很多博客的写法是用两个map来搞 都可以】
对于每个询问 直接暴力dfs【本来想求传递闭包后来发现那样复杂度更高】
上AC代码:
#include <cstring> #include <iostream> #include <algorithm> #include <set> #include <map> using namespace std; const int maxv = 2100; const int maxe = 20000; struct edge{int to, next;}E[maxe]; int head[maxv]; int si; int vis[maxv]; void addedge(int u, int v) { E[si].to = v; E[si].next = head[u]; head[u] = si++; } bool dfs(int x, int y) { if(x == y) return true; vis[x] = 1; for(int i = head[x]; i != -1; i = E[i].next) { if(vis[E[i].to] == 1) continue; if(dfs(E[i].to, y)) { return true; } } return false; } char buf[50100][110]; map<string, int> id; int nameid; int main() { //freopen("in.txt", "r", stdin); int T; scanf("%d", &T); int kase = 0; while(T--) { printf("Case #%d: ", ++kase); id.clear(); nameid = 1; si = 0; memset(E, -1, sizeof(E)); memset(head, -1, sizeof(head)); bool kaseend = false; while(!kaseend) { int loc = 0; while(true)//如果读不到标点符号就一直循环 { scanf("%s", buf[loc++]); int len = strlen(buf[loc-1]);//the last word's len if(buf[loc-1][len-1] == '!')//读到感叹号就退出 { printf(" "); kaseend = true; //kase终止标记 break; } else if(buf[loc-1][len-1] == '.')//事实陈述句 { if(loc == 3) { string a = buf[0]; buf[loc-1][len-1] = '