AT—次世代SNS 题解

题外话:这道题原来的题号是 \(\texttt{AT999}\)

题目传送门

更好的阅读体验?

题意:

给一行一个字符串,其中只包含小写字母,空格和 @@ 之后接字母的情况才合法,求被 @ 的人的名字。

  • 注意:空串不算名字!

思路:

  • \(1 \leq\) 字符串的长度 \(\leq 140\),直接暴力。

  • 可以读一个词块就判断一个词块,cin 以空格为界,省去处理空格的麻烦。

  • S.find(ss) 是寻找字符串 \(ss\)\(S\)作为子串出现时第一个字母的位置(从 \(0\) 开始),若没有返回 \(-1\)

  • S.substr(pos,n) 返回的字符串是从 \(pos\) 起的前 \(n\) 个字符,注意不要越界。

  • cin 读入失败返回 \(0\)scanf 读入失败返回 \(-1\)

  • sort 内部排字符串的方法:

  1. 先比较首字符的大小(按照 \(\texttt{ASCII}\) 码的大小)。
  2. 如果首字母不相等,可以直接按照给定标准排序(就是自己写的函数,默认由小到大)。
  3. 若相等,则按照 \(2\) 的方法继续判断下一个字符,直到有一个字符串的所有字符都判断完了,此时长度短的小于长度长的,按照给定标准排序。
  • AT 的题最后要换行!

  • 注意细节。

代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
string s,ans[101];//ans存被 @ 的人的名字
int tot;//存答案数量
int main()
{
	while(cin>>s)//一直读一个单词,可以避免很多麻烦
	{
		int nw1=s.find('@'),flag=0;
		//nw1 是找 '@' 字符的位置
		//flag 标记是否搜到最后
		while(nw1!=-1)//有 '@'
		{
			int nw2=s.find('@',nw1+1);
			//从 nw1 的下一个字符开始,寻找 '@'
			if(nw2==-1)//没有 @' 了
			{
				nw2=s.size();
				//为了使下文的 substr 不用特判
				//在全文的末尾再加一个 '@'
				//这时 '@' 的位置就是 s.size()
				flag=1;//标记已经搜到了最后
			}
			
			string wait=s.substr(nw1+1,nw2-(nw1+1));
			tot++;
			ans[tot]=wait;
			//wait 等待判断是否有重复的人名
			//先假设没有重复,后面再判断
			
			if(wait.size()==0)
			{
				//不合法情况之一:
				//是空串
				tot--;
				//不合法,数量减 1
			}
			
			for(int i=1;i<=tot-1;i++)       
			{
				if(ans[i]==wait)
				{
					//不合法情况之二:
					//有重复
					tot--;
					//不合法,数量减 1
					break;
					//不用继续判断了,跳出循环
				}
			}
			if(flag)  break;//搜到末尾了,打破循环
			nw1=nw2;
			//下一次开始判断的位置
			//就是这次判断结束的位置
		}
	}
	
	sort(ans+1,ans+tot+1);
	//sort 默认就是按字典序由小到大排序
	
	for(int i=1;i<=tot;i++)
	{
		if(ans[i].size()!=0)
		{
			//如果这个字符串不是空的,就输出
			cout<<ans[i]<<endl;
			//一行一个名字,AT 的题最后需要换行
		}
	}
	
	return 0;
}      

最快 \(5ms\)

posted @ 2025-02-08 16:43  Wy_x  阅读(17)  评论(0)    收藏  举报