江西财经大学第一届程序设计大赛 E-消息列表

本文介绍了一个消息列表排序算法,该算法能够根据好友发送消息的时间和置顶状态对消息列表进行实时排序。支持接收消息、查看消息、置顶好友、取消置顶及删除好友消息等多种操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

链接: https://www.nowcoder.com/acm/contest/115/E

来源:牛客网

题目描述

当你的好友给你发来一条消息,你的消息列表上就会置顶显示该好友的名字以及该好友发给你的消息总数,换句话说,你的消息列表里的好友是按跟你发消息的时间进行排序的,给你发消息的时间离当前时间越近的好友将排到越前面。当然,你可能会手动置顶一些好友,那么其他的好友给你发消息时,他们的名字就只能在你手动置顶好友的后面再置顶了。如果消息被你查看或者忽略,又或者你把好友消息删除了,消息总数将重置为0。

根据用户的需求,有以下几个功能,需要你来实现:
(1)recv:收到一条好友消息,对于手动置顶好友的消息,将在“手动置顶好友列表”里置顶;对于其他好友的消息,将在“手动置顶好友列表”之下的消息列表里置顶,同时都需要显示该好友的消息总数。
(2)view:查看好友消息,将使该好友消息数变为0。
(3)up:手动置顶好友。
(4)down:取消手动置顶。
(5)delete:删除好友消息,这个操作将使该好友从消息列表中删除,同时取消对该好友的手动置顶(如果存在的话)。

假设初始消息列表为空,经过了一系列好友消息的操作之后,最终的消息列表将是怎么样的呢?


输入描述:

第一行输入一个整数T(表示样例个数)
接下来T组样例。
每组样例
第一行输入一个整数M,表示操作数(1≤M≤1000000);
接下来M行,
每行输入一个操作,由一个操作类型和一个好友id构成,之间以空格分开,操作类型如上面5个英文单词表示,
例如:“recv 123456”表示接收到id为123456的好友的一条消息,“delete 123456”表示在消息列表中删除 id 为123456的好友的消息记录。
为了简化问题,一开始消息列表为空并假设好友名字id由六位数字“唯一”标识(000000≤id≤999999),
题目保证输入数据的一致性。

输出描述:

每组样例,
输出最后的消息列表,自顶向下,每行输出一个:“好友id 消息数”。
每组样例后空一行。
/*思路:除了delete操作,不用及时更新元素在vector中的位置*/
/*因为最后是在置顶的范围内按照出现时间排序,再在非置顶的范围内按照时间排序*/
/*所以只要标记好是否制定和消息最后一次出现时间即可*/

#include<bits/stdc++.h>
using namespace std;
struct info{
	//information
	string name;
	int xxts;
	//消息条数 
	int zd;
	//置顶 1=置顶 0=非置顶 
	int ti;
	//time 会根据下面的cnt来更新,ti的值越靠后代表最后一条消息的时间离现在越近 
	//第一关键字:置顶  第二关键字:出现时间 
	bool friend operator <(info a,info b)
	{
		if(a.zd!=b.zd) return a.zd>b.zd;
		else if(a.ti!=b.ti) return a.ti>b.ti;
		return 1>0;
	}
};
/*bool cmp (struct info a,struct info  b)
{
	if(a.zd!=b.zd) return a.zd>b.zd;
	else if(a.ti!=b.ti) return a.ti>b.ti;
	return 1>0;
}*/
vector<info> v;
int main()
{
	int t,m;
	int i,j,l;
	int cnt;
	string s,ss;
	vector<info>::iterator it;
	cin>>t;
	for(i=0;i<t;i++)
	{
		v.clear();
		cin>>m;
		cnt=0;
		for(j=0;j<m;j++)
		{
			cin>>s>>ss;
			if(s=="recv")
			{
				for(l=0;l<v.size();l++)
				{
					if(v[l].name==ss) break;
				}
				if(l<v.size())
				{
					v[l].ti=cnt++;
					v[l].xxts++;
				} 
				else
				{
					info x;
					x.name=ss;
					x.xxts=1;
					x.zd=0;
					x.ti=cnt++;
					v.push_back(x);
				}
			}
			else if(s=="view")
			{
				for(l=0;l<v.size();l++)
				{
					if(v[l].name==ss) break;
				}
				v[l].xxts=0;
			}
			if(s=="up")
			{
				for(l=0;l<v.size();l++)
				{
					if(v[l].name==ss) break;
				}
				v[l].zd=1;
			}
			if(s=="down")
			{
				for(l=0;l<v.size();l++)
				{
					if(v[l].name==ss) break;
				}
				v[l].zd=0;
			}
			if(s=="delete")
			{
				for(it=v.begin();it!=v.end();it++)
				{
					if((*it).name==ss) break;
				}
				v.erase(it);
			}
		}
		sort(v.begin(),v.end());
		for(j=0;j<v.size();j++)
		{
			cout<<v[j].name<<" "<<v[j].xxts<<endl;
		}
        cout<<endl;
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值