题意:模拟题。
给你n长度的数组a,以及数字k。建立一个答案数组ans,让你在现有长度不超过k的情况下,将原有数组按次序推入,如果数组中已经存在该数,则不操作,如果超出k的长度则记录最后k个数。让你输出最终的数组长度,以及数组。
直接看样例更容易理解。
依次推入数组中的数1,2,ans[]={2,1}。当推入3时,数组超过2,答案数组变为{3,,2}。再推入2,因为数组中存在2,不操作。以此类推。
分析:
-
建立数组ans,记录答案。
-
因为当长度超过k,数组有向后推的操作,所以需要记录一下要求输出的区间[l,r]。
-
因为要判断是否出现过某个数,所以要标记一下,但a[i]的范围在1~10^9,所以只能用map存储。同时如果答案数组区间移动,记得取消移出的数的标记。
-
记得倒序输出。
题解:
#include <bits/stdc++.h> #define ll long long using namespace std; const int N=2e5+5; ll a[N],ans[N]; map<ll,bool> vis; int main() { ll n,k; cin>>n>>k; for(int i=1;i<=n;i++) { scanf("%lld",&a[i]); } ll l=1,r=0; for(int i=1;i<=n;i++) { if(r<k&&!vis[a[i]]) { ans[++r]=a[i]; vis[a[i]]=1; } else if(r>=k&&!vis[a[i]]) { ans[++r]=a[i]; vis[a[i]]=1; vis[ans[l++]]=0; } } cout<<r-l+1<<endl; for(int i=r;i>=l;i--) { cout<<ans[i]<<" "; } return 0; }
(仅代表个人思考。如有错误,欢迎礼貌指正。如有疑问,欢迎友好交流。鄙人愚笨,敬请原谅。)