【信息学奥赛一本通】1148:连续出现的字符

【题目描述】

给定一个字符串,在字符串中找到第一个连续出现至少k次的字符。

【输入】

第一行包含一个正整数k,表示至少需要连续出现的次数。1 ≤ k ≤ 1000。

第二行包含需要查找的字符串。字符串长度在1到2500之间,且不包含任何空白符。

【输出】

若存在连续出现至少k次的字符,输出该字符;否则输出No。

【输入样例】

3
abcccaaab

【输出样例】

c

【代码】

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int k,sum=1,l; //k:目标点 sum:累加器 l:字符串长度
	string f;//f:字符串
	cin>>k>>f;//输入
	l=f.length();
	for(int i=0;i<l;i++)
	{
		if(sum>=k)//如果达到目标
        {
		   cout<<f[i]; //输出第一个达到目标的字符
		   return 0;
	    }
		if(f[i]==f[i+1])//如果连续出现相同字符
		   sum++;//累加
		else sum=1;//否则归一	
   }
	cout<<"No"<<endl;//如果没达成目标就输出“No"
	return 0;
}
### 关于信息学奥赛一本 1470 'Censoring' 的解法 #### 题目概述 题目描述常涉及字符串处理中的模式匹配问题。具体来说,给定一段文本和若干敏感词列表,要求将这些敏感词替换为特定字符(如星号 `*`)。此问题的核心在于高效实现多模式串匹配以及后续的替换操作。 #### 解题思路 该类问题可以采用 **AC 自动机** 来解决[^2]。以下是详细的分析: - AC 自动机构建阶段:过构建 Trie 树并计算失败指针来完成自动机初始化。这一过程的时间复杂度为 O(L),其中 L 是所有模式串总长度。 ```cpp struct ACAutomaton { struct Node { int next[26]; int fail; bool isEnd; Node() : fail(0), isEnd(false) { memset(next, 0, sizeof(next)); } }; vector<Node> trie; int sz; ACAutomaton() : sz(1) { trie.emplace_back(); } void insert(const string& s) { int cur = 0; for(char c : s){ if(!trie[cur].next[c - 'a']){ trie[cur].next[c - 'a'] = sz++; trie.emplace_back(); } cur = trie[cur].next[c - 'a']; } trie[cur].isEnd = true; } void build(){ queue<int> q; for(int i = 0;i < 26;i++){ if(trie[0].next[i]){ trie[trie[0].next[i]].fail = 0; q.push(trie[0].next[i]); } } while(!q.empty()){ int u = q.front(); q.pop(); for(int i = 0;i < 26;i++){ if(trie[u].next[i]){ int v = trie[u].next[i]; trie[v].fail = trie[trie[u].fail].next[i]; q.push(v); } else{ trie[u].next[i] = trie[trie[u].fail].next[i]; } } } } }; ``` - 字符串扫描与匹配阶段:利用已构建好的 AC 自动机,在目标文本上逐字符遍历,并记录匹配到的敏感词位置及其长度。时间复杂度同样为线性级别 O(N),其中 N 表示待检测文本长度。 - 替换操作:基于上述找到的所有匹配项,按照从右至左顺序执行替换动作以避免索引偏移影响最终结果准确性。 #### 实现细节注意事项 1. 敏感词可能存在重叠情况,因此需特别注意如何定义优先级或者冲突解决方案。 2. 输入规模较大时应考虑优化内存分配方式减少额外开销。 3. 输出格式严格遵循题目规定,尤其是当多个连续被屏蔽部分之间是否有间隔等问题。 ```cpp string processText(string text, const vector<string>& patterns){ ACAutomaton ac; for(auto &p : patterns){ ac.insert(p); } ac.build(); // Matching phase... } ``` 问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值