本题确实很锻炼编码能力。最最最重要的是选择合适的容器来存放数据。我第一次做采用了三维数组存放后遍历查询,但是由于太麻烦甚至没能完成就放弃这个方案了;第二次采用二维向量存放每一行,在查询时再分别对各行进行处理,最后虽然完成了但是不出所料:TLE。一筹莫展之际翻了翻讨论区,看到有大佬说“这道题不是暴搜就行?”我直接傻掉,赶紧点进他的主页看了他的代码,噢,原来这就是大佬的暴搜…(在代码里用到了,我的注释很详细)。借鉴之后从头开始,几次WA值之后终于AC。
WA的原因是Sorry那一句没有复制到末尾的句号,这一个小错误耗了将近一小时,心态有点炸…
题目链接:UVa 1597
AC代码:
#include <iostream>
#include <sstream>
#include <vector>
#include <set>
using namespace std;
vector<vector<string>> docs; //分别存储每篇文章
vector<set<string>> dic; //存储每篇文章中出现的所有单词
vector<set<string>> line; //存储每行中出现的所有单词
int T, N;
void oper(string s,set<string>& st) { //将整个句子拆分为无符号小写单词
string w;
set<string> word;
for (int i = 0; i < s.length(); i++) {
if (isalpha(s[i]))
s[i] = tolower(s[i]);
else
s[i] = ' ';
}
stringstream ss(s);
while (ss >> w) {
st.insert(w);
word.insert(w);
}
line.push_back(word);
}
bool find_s(string s, bool b) { //单个单词判断,b为false表示NOT
bool flag1 = false;
int cnt = 0;
for (int i = 0; i < T; i++) {
bool flag2 = false;
if (b && dic[i].count(s) || !b && !dic[i].count(s)) {
if (flag1)
cout << "----------" << endl;
flag1 = true;
flag2 = true;
}
if (flag2)
for (int j = 0; j < docs[i].size(); j++, cnt++) {
if (line[cnt].count(s) || !b)
cout << docs[i][j] << endl;
}
else
cnt += docs[i].size(); //跳到下一篇文章的起始行
}
return flag1;
}
bool find_d(string s, string t, bool b) { //多个单词判断,b为false表示AND
bool flag1 = false;
int cnt = 0;
for (int i = 0; i < T; i++) {
bool flag2 = false;
if (!b && dic[i].count(s) && dic[i].count(t) || b && (dic[i].count(s) || dic[i].count(t))) {
if (flag1)
cout << "----------" << endl;
flag1 = true;
flag2 = true;
}
if (flag2)
for (int j = 0; j < docs[i].size(); j++, cnt++) {
if (line[cnt].count(s) || line[cnt].count(t))
cout << docs[i][j] << endl;
}
else
cnt += docs[i].size(); //跳到下一篇文章的起始行
}
return flag1;
}
int main() {
string str;
cin >> T; getchar();
for (int i = 0; i < T; i++) {
vector<string> text;
set<string> s;
while (getline(cin, str) && str != "**********") {
text.push_back(str);
oper(str, s);
}
docs.push_back(text);
dic.push_back(s);
}
cin >> N; getchar();
for (int i = 0; i < N; i++) {
getline(cin, str);
int n;
if (str[0] == 'N') {
string a = str.substr(4);
if(!find_s(a, false))
cout << "Sorry, I found nothing." << endl;
}
else if ((n = str.find('A', 0)) != string::npos) {
string a = str.substr(0, n - 1);
string b = str.substr(n + 4);
if(!find_d(a, b, false))
cout << "Sorry, I found nothing." << endl;
}
else if ((n = str.find('O', 0)) != string::npos) {
string a = str.substr(0, n - 1);
string b = str.substr(n + 3);
if(!find_d(a, b, true))
cout << "Sorry, I found nothing." << endl;
}
else
if (!find_s(str, true))
cout << "Sorry, I found nothing." << endl;
cout << "==========" << endl;
}
return 0;
}