CSDN竞赛六十七期

 1、正则匹配

给你一个字符串s和一个字符模式p,请你来原生实现一个支持 '.'和'*'的正则表达式匹配。 '.' 匹配任意单个字符 '*' 匹配零 个或多个前面的那一个元素 所谓匹配,是要涵盖整个字符串s的,而不是部分字符串。

题目没给数据范围,写了一个很丑的dp,没加优化也能过,想来数据范围应该比较小。

#include <iostream>
#include <vector>
int main()
{
	std::string s, p;
	std::cin >> s >> p;
	int n = s.size(), m = p.size();
	std::vector<std::vector<bool>> dp(n + 1, std::vector<bool>(m + 1, false));
	dp[0][0] = true;
	for (int i = 0; i <= n; ++i)
	{
		for (int j = 1; j <= m; ++j)
		{
			if (p[j - 1] == '.')
				dp[i][j] = (i > 0 && dp[i - 1][j - 1]);
			else if (p[j - 1] == '*')
			{
				if (p[j - 2] == '.')
					dp[i][j] = true;
				else
				{
					dp[i][j] = dp[i][j - 2];
					for (int t = i; t >= 1; --t)
					{
						if (s[t - 1] != p[j - 2])
							break;
						dp[i][j] = dp[i][j] | dp[t - 1][j - 2];
					}
				}
			}
			else
			{
				if (i > 0)
					dp[i][j] = dp[i - 1][j - 1] && s[i - 1] == p[j - 1];
				else
					dp[i][j] = false;
			}
		}
	}
	std::cout << (dp[n][m] ? "true" : "false") << "\n";
	return 0;
}

2、生命进化书

小A有一本生命进化书,以一个树形结构记载了所有生物的演化过程。 为了探索和记录其中的演化规律,小A提出了一种 方法,可以以字符串的形式将其复刻下来,规则如下: 初始只有一个根节点,表示演化的起点,依次记录 01 字符串中的 字符, 如果记录 0,则在当前节点下添加一个子节点,并将指针指向新添加的子节点; 如果记录 1,则将指针回退到当前 节点的父节点处。 现在需要应用上述的记录方法,复刻下它的演化过程。请返回能够复刻演化过程的字符串中, 字典序最 小的 01 字符串; 注意:节点指针最终可以停在任何节点上,不一定要回到根节点。

 简单分析一下发现此题可以分治,生成所有以子节点为根的字符串后,从小到大拼接起来就是以该节点为根的答案。

#include <iostream>
#include <vector>
#include <algorithm>
struct Node
{
	int father;
	std::vector<int> son;
};
std::vector<Node> tree(10004);
std::string solve(int node)
{
	if (tree[node].son.empty())
		return "";
	else
	{
		std::vector<std::string> v;
		for (int &son : tree[node].son)
		{
			v.push_back(std::string("0") + solve(son) + "1");
		}
		std::string res;
		std::sort(v.begin(), v.end());
		for (std::string &s : v)
			res += s;
		return res;
	}
}
int main()
{
	std::string s;
	getline(std::cin, s);
	int a = 0, flag = 1, pos = 0;
	for (auto &c : s)
	{
		if (c == '-')
			flag = -1;
		else if (c >= '0' && c <= '9')
			a = a * 10 + (c - '0');
		else if (c == ',' || c == ']')
		{
			a *= flag;
			tree[pos].father = a;
			if (a != -1)
				tree[a].son.push_back(pos);
			a = 0, flag = 1, pos++;
		}
	}
	std::string ans = solve(0);
	while (ans.back() == '1')
		ans.pop_back();
	std::cout << ans;
	return 0;
}

代码中对字符串排序的复杂度较高,发现这里的字符串实际上值有‘0’和‘1’两种字符,因此可以实现一个类似于std::bitset的结构,可以使得复杂度除以64。当然这里不用优化也能过。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值