解题思路:

        这题数据以前是很水的,现在貌似更新到官方数据了。

        还是跟以前的思路一样,搜索加个记忆化,注意这里不要用 map ,map 会大大增加复杂度(那么答案只有一个了),这里

用字符串 hash,我用特殊方法得知输入最长的字符串长度是 20,如果全是 * 的话一共有 3^20 种状态,想必怎么装都装不下

(丧心病狂,大概也不会空那么多位置的吧),这里用 3 进制来存放每一个状态即可(已经是压缩到极限了,即每个数对应一个

状态),数组开爆就过了,太小的话有些状态会引起冲突,导致错误,大概就是这样。

        

        哈希(AC代码):

#include <bits/stdc++.h>
constexpr auto Inf = 0X3F3F3F3F;
typedef long long LL;
using namespace std;

namespace IO {
	inline LL read() {
		LL o = 0, f = 1; char c = getchar();
		while (c < '0' || c > '9') { if (c == '-') f = -1; c = getchar(); }
		while (c > '/' && c < ':') { o = o * 10 + c - '0'; c = getchar(); }
		return o * f;
	}
	inline char recd() {
		char o; while ((o = getchar()) != 'Q' && o != 'C'); return o;
	}
}
using namespace IO;

const int SIZE = 1E7 + 7;
string ovo; int M[SIZE], MAP[233];

int Hash() {
	unsigned long long v = 0;
	for (int pos = 0; ovo[pos]; pos++) v = v * 3 + MAP[ovo[pos]];
	return v % 9817117;
}

/* 993217 492253 9817117 */

int F() {
	int u = Hash();
	if (M[u] != Inf) return M[u];
	if (ovo.find("LOL") != string::npos) return M[u] = -1;
	if (ovo.find("*") == string::npos) return M[u] = 0;
	int res = -1;
	for (int pos = 0; ovo[pos] && res != 1; pos++)
		if (ovo[pos] == '*') {
			ovo[pos] = 'L', res = max(res, -F());
			if (res != 1)
				ovo[pos] = 'O', res = max(res, -F());
			ovo[pos] = '*';
		}
	return M[u] = res;
}

int main() {
	MAP['*'] = 0, MAP['L'] = 1, MAP['O'] = 2;
	int N, BIT = sizeof M; cin >> N;
	while (N--) {
		memset(M, Inf, BIT);
		cin >> ovo, cout << F() << endl;
	}
}



        map 的记忆化( T 掉的 40 分):

#include <bits/stdc++.h>
typedef long long LL;
using namespace std;

namespace IO {
	inline LL read() {
		LL o = 0, f = 1; char c = getchar();
		while (c < '0' || c > '9') { if (c == '-') f = -1; c = getchar(); }
		while (c > '/' && c < ':') { o = o * 10 + c - '0'; c = getchar(); }
		return o * f;
	}
	inline char recd() {
		char o; while ((o = getchar()) != 'Q' && o != 'C'); return o;
	}
}
using namespace IO;

string ovo; map<string, int> M;

int F() {
	if (M.find(ovo) != M.end()) return M[ovo];
	if (ovo.find("LOL") != string::npos) return -1;
	if (ovo.find("*") == string::npos) return  0;

	int res = -1;
	for (int pos = 0; ovo[pos]; pos++)
		if (ovo[pos] == '*') {
			ovo[pos] = 'L'; res = max(res, -F());
			ovo[pos] = 'O'; res = max(res, -F());
			ovo[pos] = '*';
		}
	return M[ovo] = res;
}

int main() {
	int N; cin >> N;
	while (N--) {
		M.clear(), cin >> ovo, cout << F() << endl;
	}
}


点赞(1)
 

0.0分

2 人评分

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

评论列表 共有 6 条评论

RioTian 3年前 回复TA
TQL
flags 3年前 回复TA
tql
HzuWHF 5年前 回复TA
@倔强小柱子 补上 Ac 代码了 qaq
HzuWHF 5年前 回复TA
@倔强小柱子 应该是这边数据也更新了
HzuWHF 5年前 回复TA
@倔强小柱子 抱歉,这边数据太水了。加个map记忆化,应该快点了,官网数据就40分,跑不动。
倔强小柱子 5年前 回复TA
输入这个"****O*****"运行超时啊