第19届PTA天梯赛 别再来这么多猫娘了(已修改AC)

        这道题没有AC,感觉有一点点怪,可能是我理解能力有点差吧,总是不太理解题目到底是个什么思路去解决这道题的。就拿原文来讲

从左到右处理文本,违禁词则按照输入顺序依次处理;对于有重叠的情况,无论计数还是替换,查找完成后从违禁词末尾继续处理

这句话我现在还没搞懂什么意思,我试了两种途径,都没有AC,最高的拿到了14分,就是有一分拿不到,我是先遍历违禁词呢,还是先遍历文本呢,两种方法我都试了,还都是不行

思路就是直接模拟,具体细节上可能导致丢分吧,一些样例过不了,这道题样例也比较多,估计出题人也觉得大家不太好理解,多搞几个样例吧~

测试样例1

上下分别 对应输入 输出

5
MaoNiang
SeQing
BaoLi
WeiGui
BuHeShi
4
BianCheng MaoNiang ba! WeiGui De Hua Ye Keyi Shuo! BuYao BaoLi NeiRong.
BianCheng <censored> ba! <censored> De Hua Ye Keyi Shuo! BuYao <censored> NeiRong.

 样例2 3 不说了,正常都能过 主要是4 5,很怪,不知道怎么顺序

 样例4

2
AB
BB
3
AAABBB
AA<censored><censored>

 样例5

2
BB
AB
3
AAABBB
AAA<censored>B

我们来看一下样例4

 第一种方式  先遍历文本,然后遍历违禁词

AA AB BB   抓到一个 改成<censored>  接着 AA AB BB   抓到一个 BB 接着改成 <censored>

输出AA<censored><censored>  没问题,是不是就是这种方式 没准,不急我们看看5

还是先遍历文本 

AAABBB  不应该抓到AB 改成<censored>吗 不是了 他直接找的BB 我···

很奇怪,写了几种方式都试了试,还是AC不了,大家点点我,没准你们一句话就能解救我于水火之中~~~

代码附上,虽然没有AC 害~

// #include<iostream>
// #include<vector>
// #include<string>
// #include<algorithm>
// using namespace std;
// int main()
// {
// 	int n;
// 	cin >> n;
// 	vector<string> se;
// 	string str;
// 	for (int i = 0; i < n; i++)
// 	{
// 		cin >> str;
// 		se.push_back(str);
// 	}
// 	int limits, num = 0;
// 	cin >> limits;
// 	getchar();
// 	getline(cin, str);
// 	for (auto i : se)
// 	{
// 		int cnt = str.find(i);
// 		while (cnt != -1)
// 		{
// 			num++;
// 			cnt = str.find(i, cnt + i.size());
// 		}
// 	}
// 	if (num >= limits)
// 	{
// 		cout << num << "\n";
// 		cout << "He Xie Ni Quan Jia!";
// 	}
// 	else
// 	{
// 		for (auto i : se)
// 		{
// 			int cnt = str.find(i);
// 			while (cnt != -1)
// 			{
// 				str.replace(cnt, i.size(), "<censored>");
// 				cnt = str.find(i, cnt + 10);
// 			}
// 		}
// 		cout << str;
// 	}
// 	return 0;
// }

#include<vector>
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
int main()
{
	int n;
	cin >> n;
	vector<string> ve;
	string str;
	for (int i = 0; i < n; i++)
	{
		cin >> str;
		ve.push_back(str);
	}
	int limits, num = 0;
	cin >> limits;
	getchar();
	getline(cin, str);
	for (int i = 0; i < str.size(); i++)
	{
		for (auto it : ve)
		{
			string s = str.substr(i, it.size());
			if (s == it)
			{
				num++;
				str.replace(i, it.size(), "<censored>");
				i = i + 10 - 1;
				break;
			}
		}
	}
	if (num >= limits)
	{
		cout << num << "\n";
		cout << "He Xie Ni Quan Jia!";
	}
	else
		cout << str;

	//for (auto i : se)
	//{
	//	int cnt = str.find(i);
	//	while (cnt != -1)
	//	{
	//		num++;
	//		cnt = str.find(i, cnt + i.size());
	//	}
	//}
	//if (num >= limits)
	//{
	//	cout << num << "\n";
	//	cout << "He Xie Ni Quan Jia!";
	//}
	//else
	//{
	//	for (auto i : se)
	//	{
	//		int cnt = str.find(i);
	//		while (cnt != -1)
	//		{
	//			str.replace(cnt, i.size(), "<censored>");
	//			cnt = str.find(i, cnt + 10);
	//		}
	//	}
	//	cout << str;
	//}
	return 0;
}

修改后

      今天终于把这道题搞懂了,这道题的题目我感觉就很让人误解啊,除此之外还有一个坑点就是,大家注意违禁词里面有咩有可能就有<censored>,如果你超时了,一定是因为你去遍历违禁词的时候,直接把它们替换成了<censored>,导致一直find到违禁词,你就得一直替换下去,所以会超时,我们只需要做个修改就好,先将违禁词替换成不可能出现在字符串中的字符。

        题目说大小写字母、数字、空格及 ASCII 码范围内的标点符号,所以我们可以排除这几个使用“-”或者“=”,它们不是标点符号吧,更不是字母、数字等,所以行得通。

        为什么说让人误解呢,大家看上面我提到的到底怎么个搜索方式呢,有两种,让人模棱两可,其实主要是这句话误导了包括我在内的很多人。

        从左到右处理文本,违禁词则按照输入顺序依次处理;对于有重叠的情况,无论计数还是替换,查找完成后从违禁词末尾继续处理。(这段文本在代码中都有体现,仔细看注释)

        题目其实只是想告诉你啊,每次你去查找违禁词的时候,记得从左到右(我用你说,,),所以呢,真正的方式应该是按顺序遍历违禁词,一直到该字符串中没有该违禁词为止我才能去查找下一个违禁词,所以你懂怎么写了嘛~

废话少说上代码

#include<iostream>
#include<vector>
#include<string>
using namespace std;
int main() 
{
    int n; 
    cin >> n;
    vector<string>v;
    for (int i = 0; i < n; i++) 
    {
        string t;
        cin >> t;
        v.push_back(t);
    }
    int k; 
    cin >> k;
    getchar();
    string s; 
    getline(cin, s);
    int sum = 0;
    for (int i = 0; i < v.size(); i++)     //违禁词则按照输入顺序依次处理
    {
        int cnt = s.find(v[i]);
        while ( cnt!= -1)
        {
            sum++;
            s.replace(s.find(v[i]), v[i].size(), "-");
            cnt = s.find(v[i], cnt + 1);        //查找完成后从违禁词末尾继续处理
        }
    }
    while (s.find("-") != -1) 
        s.replace(s.find("-"), 1, "<censored>");//记得替换回来,要是超过了限制,不替换也可
    if (sum >= k)                               //因为压根不输出它
    {
        cout << sum<< endl;
        cout << "He Xie Ni Quan Jia!";
    }
    else
        cout << s << endl;
    return 0;
}

AC了,现在想想也没有那么难~害

大家不懂多多评论区交流,互相请教互相帮助,没准别人一句话就点通你(亲身经历)

 期待和大家共同加油,希望大家不断进步!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值