Social Network (easy version)

Social Network (easy version)

CodeForces 1234B1

这是一道我曾经训练时做过的一道题,为了应对上面的要求指标我不得不把它掏了出来(doge),这道题还是有点代表性的所以写个记录

一、题目内容

The only difference between easy and hard versions are constraints on n and k .

You are messaging in one of the popular social networks via your smartphone. Your smartphone can show at most k most recent conversations with your friends. Initially, the screen is empty (i.e. the number of displayed conversations equals 0 ).

Each conversation is between you and some of your friends. There is at most one conversation with any of your friends. So each conversation is uniquely defined by your friend.

You (suddenly!) have the ability to see the future. You know that during the day you will receive nn messages, the i -th message will be received from the friend with ID idi(1≤idi≤10^9).

If you receive a message from idi in the conversation which is currently displayed on the smartphone then nothing happens: the conversations of the screen do not change and do not change their order, you read the message and continue waiting for new messages.

Otherwise (i.e. if there is no conversation with idi on the screen):

· Firstly, if the number of conversations displayed on the screen is kk , the last conversation (which has the position k ) is removed from the screen.
· Now the number of conversations on the screen is guaranteed to be less than k and the conversation with the friend idi is not displayed on the screen.
· The conversation with the friend idi appears on the first (the topmost) position on the screen and all the other displayed conversations are shifted one position down.

Your task is to find the list of conversations (in the order they are displayed on the screen) after processing all n messages.

输入格式
The first line of the input contains two integers n and k (1≤n,k≤200) — the number of messages and the number of conversations your smartphone can show.

The second line of the input contains n integers id1, id2,……, idn(1≤idi≤10^9), where idi is the ID of the friend which sends you the i -th message.

扫描二维码关注公众号,回复: 12142068 查看本文章

输出格式
In the first line of the output print one integer m (1≤m≤min(n,k) ) — the number of conversations shown after receiving all n messages.

In the second line print m integers ids1, ids2, ……, idsn, where idsi should be equal to the ID of the friend corresponding to the conversation displayed on the position i after receiving all n messages.

题意翻译
你知道了将来N次给你发送的消息,而聊天软件一次性只能显示与K(1≤K≤200)个人的聊天记录。

当收到一条消息时,如果与这个人的聊天记录显示在聊天软件中,就什么都不做(注意,不需要把当前聊天记录置顶);否则,如果当前已经显示了K个聊天记录,则删除最后一个聊天记录;添加与这个人的聊天记录在列表顶端,同时其他聊天记录下移一个位置。

询问在这N条消息发送之后,你的聊天软件最终会显示与哪几个人的聊天记录。

输入格式
第一行两个正整数N,K(1≤N,K≤200),表示N条发来的消息和一次性显示的聊天记录个数。

接下来一行N个正整数id[i] (1≤id[i]≤200),为第i条消息的发送者。

输出格式
第一行,输出最后屏幕上显示的聊天记录个数X。

接下来一行X个正整数,按顺序输出最后屏幕上显示的聊天记录的对象。

说明/提示:In the first example the list of conversations will change in the following way (in order from the first to last message):
[];
[1];
[2, 1];
[3, 2];
[3, 2];
[1, 3];
[1, 3];
[2, 1].

In the second example the list of conversations will change in the following way:
[] ;
[2] ;
[3, 2];
[3, 2];
[1, 3, 2];

and then the list will not change till the end.

输入输出样例

输入#1

7 2
1 2 3 2 1 3 2

输入#2

10 4
2 3 3 1 1 2 1 2 3 3

输出#1

2
2 1 

输出#2

3
1 3 2 

二、个人思路

跟QQ,微信差不多,屏幕只能容纳k个消息(如果你不往下拉),不同的是这道题规定新消息的会话窗口已经出现在屏幕里,不会置顶,只有屏幕外的会话窗口发出新消息,才会置顶并且把最下面的消息顶出去。也没有人工置顶。
这里首先用一个映射b来维护当前记录里存在的记录,每读入一个数据先判断是否在记录里,如果不在则写入并进行判断,代码如下:

#include<stdio.h>
#include<map>
using namespace std;
map<int,bool>b;
const int N=200020;
int a[N];
int main()
{
    
    
	int n,k,m=0,s=0,t,i;
	scanf("%d%d",&n,&k);//n条发来的信息和当前最多k条显示聊天记录
	for(i=0;i<n;i++)
	{
    
    
		scanf("%d",&t);//有t个人发来消息
		if(!b[t])//如果之前没有这个人的消息
		{
    
    
			b[t]=true;//新增记录,写入
			a[++m]=t;
			if(m-s>k)//消息数超过显示数
				b[a[++s]]=false;//把最下面那一条顶下去
		}
	}
	printf("%d\n",m-s);//屏幕最后显示的消息条数
	while(m>s)
		printf("%d ",a[m--]);//聊天对象
	return 0;
}

---------------------------------------分割线-----------------------------------------

上面的代码是我还在是小蒟蒻的时候写的代码,后来成了大蒟蒻(悲)我发现用队列也可以做,这道题很符合队列先进先出的特点,若当前队列长度为 k,则队列第 k 个位置的元素出队,如果队列长度小于 k 并且 idi 没在队列中出现过,则 idi 将进入队列头部,其他的元素向后移一位,最后输出队列,下面贴个代码:

#include<iostream>
#include<queue>
#include<map>
using namespace std;
queue<int>q;//使用STL模板
map<int,bool>b;
int a[200020];
int main()
{
    
    
    int n,k,x;
    cin>>n>>k;
    for(int i=1;i<=n;i++)
    {
    
    
        cin>>x;
        if(!b[x])//入队
        {
    
    
            b[x]=1;
            q.push(x);
        }
        if(q.size()>k)//出队
        {
    
    
            b[q.front()]=0;
            q.pop();
        }
    }
    int t=q.size();
    cout<<t<<endl;
    for(int i=1;i<=t;i++)
    {
    
    
        a[i]=q.front();
        q.pop();
    }
    for(int i=t;i>=1;i--)
        cout<<a[i]<<" ";
    cout<<endl;
    return 0;
}

以上代码均在洛谷平台检验过,均AC

总结

这道题如果你熟悉算法而且理解题意之后就比较好做了,可以用一个数组或者一个队列来维持当前记录,根据题意进行模拟

猜你喜欢

转载自blog.csdn.net/jotaro07/article/details/110265947