原题链接:https://codeforces.com/contest/1234/problem/B2
你正在一个流行的社交网络中通过智能手机发送信息。你的智能手机最多可以显示k个最近与朋友的对话。最初,屏幕是空的(即显示的对话数等于0)。 每次谈话都是你和你的一些朋友之间的。最多只能和你的朋友进行一次谈话。所以每次谈话都是由你的朋友来定义的。 现在你(突然!)有能力看到未来。你知道在一天中你将收到n条信息,第i条信息将从id为idi(1≤idi≤10^9)的朋友处收到。 如果在智能手机当前显示的对话中收到来自IDI的消息,则不会发生任何事情:屏幕上的对话不会更改,也不会更改其顺序,您将阅读该消息并继续等待新消息。 否则(即,如果屏幕上没有与IDI的对话): 首先,如果屏幕上显示的对话数为k,则从屏幕上删除最后一个对话(位置为k)。 现在,屏幕上的对话数保证小于k,并且与朋友idi的对话不会显示在屏幕上。 与朋友idi的对话出现在屏幕的第一个(最上面的)位置,所有其他显示的对话都向下移动一个位置。 你的任务是在处理完所有n条消息后查找对话列表(按对话在屏幕上显示的顺序)
Input
输入的第一行包含两个整数n和k(1≤n,k≤2e5)-您的智能手机可以显示的消息数和对话数。 输入的第二行包含n个整数id1,id2,…,idn(1≤id i≤10^9),其中idi是向您发送第i条消息的朋友的id。
Output
在输出的第一行中,打印一个整数m(1≤m≤m in(n,k))——接收所有n条消息后显示的会话数。 在第二行中,打印m个整数ids1、ids2、…、idsm,其中idsi应等于收到所有n条消息后显示在位置i上的对话对应的朋友的id。
Examples
Input
7 2
1 2 3 2 1 3 2
Output
2
2 1
Input
10 4
2 3 3 1 1 2 1 2 3 3
Output
3
1 3 2
注:这是有两个题的,只不过一个题增加了范围而已,我这里贴的是范围较大的那个题。
题意:你会不断收到n条信息,遵循先来后到的原则,先来的占前面位置,后来的往后移,遵循有了就叠加的规则,窗口最多只能显示k条信息,问最后接受完信息后屏幕上还剩多少条,输出这些信息。
解题思路:这明显就是一个入队+出队的问题,但这里还要注意一个小细节,已经入队了的就不用入队了,所以我们还要作标记,可以使用visited数组来实现标记,也可以利用map来标记,我比赛的时候用的是map,没想太多,这里其实用visited更简单一点,入队和出队均改标记即可。那么最后输出的时候是要从队尾开始输出的,所以我们可以使用双端队列deque,或者利用栈来转移输出操作。
AC代码:
/* *邮箱:2825841950@qq.com *blog:https://blog.csdn.net/hzf0701 *注:代码如有问题请私信我或在评论区留言,谢谢支持。 */
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<string>
#include<stack>
#include<queue>
#include<cstring>
#include<map>
#include<iterator>
#include<list>
#include<set>
#include<functional>
#include<memory.h>//低版本G++编译器不支持,若使用这种G++编译器此段应注释掉
#include<iomanip>
#include<vector>
#include<cstring>
#define scd(n) scanf("%d",&n)
#define scf(n) scanf("%f",&n)
#define scc(n) scanf("%c",&n)
#define scs(n) scanf("%s",n)
#define prd(n) printf("%d",n)
#define prf(n) printf("%f",n)
#define prc(n) printf("%c",n)
#define prs(n) printf("%s",n)
#define rep(i,a,n) for (int i=a;i<=n;i++)//i为循环变量,a为初始值,n为界限值,递增
#define per(i,a,n) for (int i=a;i>=n;i--)//i为循环变量, a为初始值,n为界限值,递减。
#define pb push_back
#define fi first
#define se second
#define mp make_pair
using namespace std;
const int inf = 0x3f3f3f3f;//无穷大
const int maxn = 2e5+2;//最大值。
typedef long long ll;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;
//*******************************分割线,以上为代码自定义代码模板***************************************//int main(){//freopen("in.txt", "r", stdin);//提交的时候要注释掉ios::sync_with_stdio(false);//打消iostream中输入输出缓存,节省时间。cin.tie(0); cout.tie(0);//可以通过tie(0)(0表示NULL)来解除cin与cout的绑定,进一步加快执行效率。ll n,k;ll id[maxn];while(cin>>n>>k){rep(i,0,n-1){cin>>id[i];}map<ll,ll> p;queue<ll> q;ll temp1,temp2;rep(i,0,n-1){if(!p[id[i]]){q.push(id[i]);}temp2=q.size();//判断消息列表是否满了。p[id[i]]++;if(temp2>k){temp1=q.front();p.erase(temp1);q.pop();}}cout<<q.size()<<endl;stack<ll> s;while(!q.empty()){s.push(q.front());q.pop();}while(!s.empty()){cout<<s.top()<<" ";s.pop();}cout<<endl;}return 0;
}