L1-101 别再来这么多猫娘了!
L1-101 别再来这么多猫娘了!
完整原题
以 GPT 技术为核心的人工智能系统出现后迅速引领了行业的变革,不仅用于大量的语言工作(如邮件编写或文章生成等工作),还被应用在一些较特殊的领域——例如去年就有同学尝试使用 ChatGPT 作弊并被当场逮捕(全校被取消成绩)。相信聪明的你一定不会犯一样的错误!
言归正传,对于 GPT 类的 AI,一个使用方式受到不少年轻用户的欢迎——将 AI 变成猫娘。
当然,由于训练数据里并不区分道德或伦理倾向,因此如果不加审查,AI 会生成大量的、不一定符合社会公序良俗的内容。尽管关于这个问题仍有争论,但至少在比赛中,我们还是期望 AI 能用于对人类更有帮助的方向上,少来一点猫娘。
因此你的工作是实现一个审查内容的代码,用于对 AI 生成的内容的初步审定。更具体地说,你会得到一段由大小写字母、数字、空格及 ASCII 码范围内的标点符号的文字,以及若干个违禁词以及警告阈值,你需要首先检查内容里有多少违禁词,如果少于阈值个,则简单地将违禁词替换为<censored>;如果大于等于阈值个,则直接输出一段警告并输出有几个违禁词。
输入格式:
输入第一行是一个正整数 N (1≤N≤100),表示违禁词的数量。接下来的 N 行,每行一个长度不超过 10 的、只包含大小写字母、数字及 ASCII 码范围内的标点符号的单词,表示应当屏蔽的违禁词。
然后的一行是一个非负整数 k (0≤k≤100),表示违禁词的阈值。
最后是一行不超过 5000 个字符的字符串,表示需要检查的文字。
从左到右处理文本,违禁词则按照输入顺序依次处理;对于有重叠的情况,无论计数还是替换,查找完成后从违禁词末尾继续处理。
输出格式:
如果违禁词数量小于阈值,则输出替换后的文本;否则先输出一行一个数字,表示违禁词的数量,然后输出He Xie Ni Quan Jia!。
输入样例1:
5
MaoNiang
SeQing
BaoLi
WeiGui
BuHeShi
4
BianCheng MaoNiang ba! WeiGui De Hua Ye Keyi Shuo! BuYao BaoLi NeiRong.
输出样例1:
BianCheng <censored> ba! <censored> De Hua Ye Keyi Shuo! BuYao <censored> NeiRong.
输入样例2:
5
MaoNiang
SeQing
BaoLi
WeiGui
BuHeShi
3
BianCheng MaoNiang ba! WeiGui De Hua Ye Keyi Shuo! BuYao BaoLi NeiRong.
输出样例2:
3
He Xie Ni Quan Jia!
输入样例3:
2
AA
BB
3
AAABBB
输出样例3:
<censored>A<censored>B
代码
#include <algorithm> // 字符串操作函数库(find/erase/insert 可用)
#include <iostream> // 输入输出流(cin / cout 必须用)
#include<bits/stdc++.h> // C++ 万能头文件(包含所有常用库,比赛专用)
using namespace std;
int n;
string arr[200];
string str;
int cnt=0;
int k;
string s="<censored>";
/*
避免替代的字符串中再有违禁词
*/
int main() {
cin>>n;
for(int i=0;i<n;i++){
cin>>arr[i];
}
cin>>k;
getchar();//读取空行
getline(cin,str);
for(int i=0;i<n;i++){
while(1){
if(str.find(arr[i])!=-1){//看能不能找到
cnt++;
int pos=str.find(arr[i]);
str.erase(pos,arr[i].size());//找到就删除
str.insert(pos,"*_*");//先用一个不含字符数字的标识符代替
}
else break;
}
}
if(cnt<k){//如果违禁词小于阈值
while(str.find("*_*")!=-1){
int poss=str.find("*_*");
str.erase(poss,3);
str.insert(poss,s);
}
cout<<str;
}
else {//如果违禁词大于等于阈值
cout<<cnt<<endl;
cout<<"He Xie Ni Quan Jia!";
}
return 0;
}
#include<iostream>
#include<algorithm>
#include<bits/stdc++.h>
using namespace std;
int n;
int k;//表示违禁词的阈值。
string s="<censored>";
string str;//表示需要检查的文字
string arr[105];//,表示应当屏蔽的违禁词
int cnt =0;//目前的违禁词
int main (){
cin>>n;
for(int i=0;i<n;i++){
cin>>arr[i];
}
cin>>k;
getchar();//读取空行
getline(cin,str);
for(int i=0;i<n;i++){
size_t pos;
//size_t 是 无符号整数(专门给字符串、数组用),str.find() 返回的就是 size_t 类型
//它在#include <string>或者#include <bits/stdc++.h>
while((pos=str.find(arr[i]))!=string::npos){
cnt++;
str.replace(pos,arr[i].size(),"*_*");
}
}
if(cnt>=k){
cout<<cnt<<endl;
cout<<"He Xie Ni Quan Jia!";
}else{
size_t pos;
while((pos=str.find("*_*"))!=string::npos){
cnt++;
str.replace(pos,3, s);
}
cout<<str;
}
}
代码中核心函数详解
1. cin >> 变量
- 作用:从标准输入读取数据,自动跳过空白字符(空格、换行、制表符)。
- 使用场景:读取整数
n、k,以及不含空格的违禁词arr[i]。 - 注意:读取后会在输入缓冲区留下换行符,需配合
getchar()处理。
2. getchar()
-
作用:从输入缓冲区读取一个字符(通常用于“吃掉”多余的换行符)。
-
使用场景:在
cin >> k后调用,避免getline()读到空行。 -
原理:
cin >> k读完数字后,换行符仍在缓冲区,getchar()会将其读取并丢弃。 -
只有一种情况需要 getchar()
✅ 当你接下来要读 字符 / 字符串 时!
❌ 读数字(int、float)绝对不需要! -
cin >> 数字
会自动跳过: -
空格
-
换行
-
回车
所以读数字时:
cin >> index >> num;
换行符自动忽略,根本不用处理!
- cin >> 字符 / getline()
不会跳过换行符!
换行符\n会被当成一个字符读走!
导致你读不到真正想要的字符!
3. getline(cin, str)
- 作用:读取一整行字符串(包含空格和标点),直到遇到换行符为止。
- 使用场景:读取带空格的待检查文本
str。 - 注意:必须先处理
cin留下的换行符,否则会读到空字符串。
4. str.find(子串)
-
作用:在字符串
str中查找子串第一次出现的位置。 -
返回值:找到则返回起始下标(
int),未找到则返回string::npos(可写为-1)。 -
使用场景:判断是否存在违禁词
arr[i],并获取其位置。 -
示例:
str.find("AA")在"AAABBB"中返回0。 -
写 string::npos
:: 叫 作用域符号
作用:告诉编译器,这个 npos 属于 string 类
就像 姓名::姓氏
意思:这是字符串里专用的 “没找到” 标记:: = 属于、专用
npos = no position = 没找到位置
string::npos = 字符串里表示“找不到”的固定值
= 代表“没找到”
5. str.erase(起始位置, 长度)
- 作用:从字符串中删除指定位置开始、指定长度的字符。
- 使用场景:删除找到的违禁词,为替换占位符做准备。
- 示例:
str.erase(0, 2)会删除从位置0开始的 2 个字符。
6. str.insert(位置, 插入内容)
- 作用:在字符串的指定位置插入新的字符串。
- 使用场景:
- 第一轮:插入占位符
*_*替换违禁词。 - 第二轮:插入
<censored>替换占位符*_*。
- 第一轮:插入占位符
- 示例:
str.insert(0, "*_*")在位置0插入占位符。
7. str.size()
- 作用:返回字符串的字符长度。
- 使用场景:获取违禁词
arr[i]的长度,用于erase()操作。 - 示例:
"AA".size()返回2。
8. cout << 内容
- 作用:向标准输出打印内容。
- 使用场景:输出替换后的文本,或违禁词数量与警告语。
- 注意:输出文本时需保留原格式(空格、标点),警告语后需换行。
9. str.replace(pos, arr[i].size(), "*_*");
- 作用:替换字符串里的一段文字!**
- 三个参数分别是:
str.replace(从哪里开始, 替换多长, 换成什么);

| 函数 | 作用 | 核心使用场景 |
|---|---|---|
cin >> | 读取无空格数据 | 读整数、违禁词 |
getchar() | 读取单个字符 | 吃掉缓冲区换行符 |
getline() | 读取整行文本 | 读带空格的待检查文本 |
str.find() | 查找子串位置 | 查找违禁词 |
str.erase() | 删除指定字符 | 删除违禁词 |
str.insert() | 插入字符串 | 替换为占位符/屏蔽词 |
str.size() | 获取字符串长度 | 计算违禁词长度 |
cout << | 输出内容 | 输出结果 |
1万+



被折叠的 条评论
为什么被折叠?



