P6565 [NOI Online #3 入门组] 最急救助
#include<bits/stdc++.h>
using namespace std;
inline int read() // 快读,传统艺能
{
int x=0,f=1;
char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-')
{
f=-1;
}
ch=getchar();
}
while(isdigit(ch))
{
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return x*f;
}
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
bool operator==(string x,string y) // 重载==运算符,bool类型
{
if(x.length()==y.length()) // 如果长度相等,继续判断
{
for (ll i = 0; i < x.length(); i++) // 循环比较两个字符串每个字符是否相等
{
if(x.at(i)!=y.at(i)) // 如果遇到不相等的直接返回false然后break跳出循环
{
return false;
break;
}
}
return true; // 如果循环一圈下来没有不相等的,说明两字符串相等,返回true
}
else // 长度不相等直接返回false(这题不会出现这个情况)
{
return false;
}
}
struct sign // 定义sign结构体维护每个信号
{
string name; // 求助者姓名
string message; // 求助者信息
ll cnt; // cnt记录sos字符串数量
ll innum; // 输入顺序
};
const string str="sos"; // 定义比较常量,字符串都与str比较
int TongJi(sign m) // 核心算法,返回每个sign的cnt
{
string tmp; // 定义tmp字符串每次从sign的message中读入连续的3个字符
ll temp=0; // 定义temp变量用于记录cnt
for (ll i = 0; i+2 < m.message.length(); i++) // tmp的右界为message的结尾,所以i+2小于message长度
{
tmp=m.message.substr(i,3); // 从message中读入从i到i+2的3个字符
if(tmp==str) // tmp[0]=='s'&&tmp[1]=='o'&&tmp[2]=='s'
{
temp++; // 如果相等,计数器+1
}
tmp.clear(); // 避免出错,清空tmp字符串
}
return temp; // 返回计数器,cnt
}
inline int cmpcnt(sign x,sign y) // 自定义排序
{
if(x.cnt==y.cnt) // 如果sos个数相同,则按输入顺序返回
{
return x.innum<y.innum;
}
return x.cnt<y.cnt; // sos个数不同就按cnt顺序返回
}
ll n; // n组数据
int main()
{
n=read(); // 唯一一个用到快读的变量
sign a[n]; // sign类型一维数组,长度n
for (ll i = 0; i < n; i++) // 循环读入,getline比cin快
{
getline(cin,a[i].name); // 读入姓名
getline(cin,a[i].message); // 读入求助信息
a[i].innum=i+1; // 记录输入顺序
}
for (ll i = 0; i < n; i++)
{
a[i].cnt=TongJi(a[i]); // 循环遍历数组,依次处理每个sign的cnt
}
sort(a,a+n,cmpcnt); // 按照自定义排序排序数组a
ll r=0; // 定义最大cnt
r=a[n-1].cnt; // 给最大cnt赋值
for (ll i = n-1; i >= 0; i++) // 循环输出
{
if(a[i].cnt!=r) // 如果遇到一个sign的cnt小于最大的cnt,则break跳出循环
{
break;
}
cout<<a[i].name<<" "; // 依次输出符合要求的求助者姓名
}
cout<<endl; // 输出后换行
cout<<r<<endl; // 输出最大的cnt
return 0;
}