Searching the Web UVA - 1597
Posted jionkitten
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Searching the Web UVA - 1597相关的知识,希望对你有一定的参考价值。
链接:https://vjudge.net/problem/UVA-1597#author=0
这题写了我一个晚上,然后debug了一个早上。。
最主要就是AND那一部分,一开始用了一个很奇怪的方法实现,就是利用set递增的性质,设置一个cur变量保存现在遍历到的文章下标的最大值,然后检查s1和s2能否取到,cur每次取当前s1和s2的文章下标最大值。中间实现的时候也出了点bug,没有在遍历到末尾的时候跳出循环。然而这不是重点。。重点在于cur不一定取到,也就是可以跳过cur取一个更大的值, 这个时候就与cur的定义就产生了矛盾。如果要在这基础上修改的话估计就是把不等号改为小于号,然而我已经懒得写了,用最原始的方法过了(不过还是出了点bugQAQ,忘记了可重性)。有些时候没办法就换个方法写,像这种情况以我的智商真的很难想到,如果不假想构造模拟数据的话。经验的话就是明确关键变量的定义,就是有特殊性质的那些,然后看后面的程序有没有违反或者可能破坏这个定义,不过这真的很难想到。。模拟数据大法好
#include <iostream> #include <cstdio> #include <cstring> #include <map> #include <set> #include <sstream> #include <cctype> #include <algorithm> #include <bitset> #define _for(i, a, b) for (int i = (a); i < (b); ++i) #define _rep(i, a, b) for (int i = (a); i <= (b); ++i) //#define fre //#define DEBUG using namespace std; struct Pos { int d, l; Pos(int d, int l): d(d), l(l) {} bool operator < (const Pos& b) const { if (d == b.d) return l < b.l; else return d < b.d; } }; map<string, set<Pos> > lib; string doc[105][1505]; string stdize(string s) { for (char& c : s) { if (!isalpha(c)) c = ‘ ‘; //这里没看清题意,题目要求忽略所有非字母字符,英语不好哭了 else c = tolower(c); } return s; } int main() { #ifdef fre freopen("in.in", "r", stdin); freopen("out.txt", "w", stdout); #endif set<Pos> tmp, s1, s2; int d, l, n, cur; bool fir = true; string word, line, a, b, c; char buf[3]; bitset<105> bit; int com[105]; scanf("%d", &d); fgets(buf, 3, stdin); for (int i = 0; i < d; ++i) { l = 0; while (getline(cin, doc[i][l]) && doc[i][l][0] != ‘*‘) { stringstream ss(stdize(doc[i][l])); while (ss >> word) { lib[word].insert(Pos(i, l)); /*#ifdef DEBUG cout << word << " : " << endl; cout << i << "-" << l << endl; #endif*/ } ++l; //fgets(buf, 3, stdin); } } scanf("%d", &n); fgets(buf, 3, stdin); //在标准输入后记得吞换行符 while (n-- && getline(cin, line)) { fir = true; stringstream ss(line); ss >> a; if (ss >> b) { if (ss >> c) { tmp.clear(); s1 = lib[stdize(a)]; s2 = lib[stdize(c)]; /*#ifdef DEBUG cout << a << endl; for (auto& i : s1) cout << i.d << " " << i.l << endl; cout<< c << endl; for (auto& i : s2) cout << i.d << " " << i.l << endl; #endif */ //万恶之源,就是这一段 if (b[0] == ‘A‘) { memset(com, 0, sizeof(com)); for (auto& i : s1) com[i.d] = 1; for (auto& i : s2) { if (com[i.d] == 1) com[i.d] = 2; } for (auto& i : s1) { if (com[i.d] == 2) tmp.insert(i); } for (auto& i : s2) { if (com[i.d] == 2) tmp.insert(i); } } else set_union(s1.begin(), s1.end(), s2.begin(), s2.end(), inserter(tmp, tmp.begin())); for (auto& i : tmp) { if (fir) cur = i.d, fir = false; else if (i.d > cur) cout << "---------- ", cur = i.d; cout << doc[i.d][i.l] << ‘ ‘; } } else { bit.set(); for (auto& i : lib[stdize(b)]) bit[i.d] = 0; for (int i = 0; i < d; ++i) { if (bit[i]) { if (fir) fir = false; else cout << "---------- "; int j = 0; while (doc[i][j][0] != ‘*‘) cout << doc[i][j++] << endl; } } } } else { for (auto& i : lib[stdize(a)]) { if (fir) cur = i.d, fir = false; else if (i.d > cur) cout << "---------- ", cur = i.d; cout << doc[i.d][i.l] << ‘ ‘; } } if (fir) cout << "Sorry, I found nothing. "; cout << "========== "; //fgets(buf, 3, stdin); } }
以上是关于Searching the Web UVA - 1597的主要内容,如果未能解决你的问题,请参考以下文章
ZOJ3228 Searching the String(AC自动机)
ZOJ - 3228 Searching the String (AC自己主动机)