UVa 1597

这道题仍然是做了3个月,一直超时和WA,最后参考某大神的AC代码终于过了。巧妙的地方就是运用||和&&来进行搜索时的“和”和“或”操作,另外分析文章后的存储数据的数据结构也很重要,还有代码中很多重复的地方不妨#define了,可以使代码更加简洁。不过最后AC还是用了1.1秒,貌似有用字典树做的方法会更快吧。

#include <bits/stdc++.h>
using namespace std;
using State = bool[1505];
#define FOR for (int j = limit[i]; j < limit[i + 1]; ++j)

map<string, State> Index;
vector<string> doc;
int limit[128];

void insert(string s, const int no){
	doc.push_back(s);
	for (auto & i : s){
		if (isalpha(i)) i = tolower(i);
		else i = ' ';
	}
	stringstream ss(s); string word;
	while (ss >> word)
		Index[word][no] = true;
}

int main()
{
	ios::sync_with_stdio(false);
	int N, cnt = 0; cin >> N; cin.get();
	for (int n = 0; n < N; ++n) {
		string line;
		while (getline(cin, line)){
			if (line == "**********"){
				limit[n + 1] = cnt;
				break;
			}
			else insert(line, cnt++);
		}
	}
	int M; cin >> M; cin.get();
	while (M--){
		string cmd; getline(cin, cmd);
		bool *A, *B;
		State out = {0};
		if (cmd[0] == 'N'){
			A = Index[cmd.substr(4)];
			for (int i = 0; i < N; ++i){
				bool flag = true;
				FOR if (A[j]) { flag = false; break; }
				FOR out[j] = flag;
			}
		}
		else if (cmd.find("AND") != string::npos){
			A = Index[cmd.substr(0, cmd.find(" AND "))];
			B = Index[cmd.substr(cmd.find(" AND ")+5)];
			for (int i = 0; i < N; ++i){
				bool flagA = false, flagB = false;
				FOR if (A[j]) { flagA = true; break; }
				FOR if (B[j]) { flagB = true; break; }
				if (flagA && flagB) FOR out[j] = A[j] || B[j];
			}
		}
		else if (cmd.find("OR") != string::npos){
			A = Index[cmd.substr(0, cmd.find(" OR "))];
			B = Index[cmd.substr(cmd.find(" OR ") + 4)];
			for (int i = 0; i < cnt; ++i) out[i] = A[i] || B[i];
		}
		else memcpy(out, Index[cmd], sizeof(State));

		bool has_out = false;
		for (int i = 0; i < N; ++i){
			bool need_out = false;
			FOR if (out[j]) {need_out = true; break;}
			if (need_out){
				if (has_out) cout << "----------" << endl;
				FOR if (out[j]) cout << doc[j] << endl;
				has_out = true;
			}
		}
		if (!has_out) cout << "Sorry, I found nothing." << endl;
		cout << "==========" << endl;
	}
	return 0;
}


原文地址:https://www.cnblogs.com/kunsoft/p/5312709.html