Codeforce69E Subsegments(集合set)

Subsegments

Programmer Sasha has recently begun to study data structures. His coach Stas told him to solve the problem of finding a minimum on the segment of the array in , which Sasha coped with. For Sasha not to think that he had learned all, Stas gave him a new task. For each segment of the fixed length Sasha must find the maximum element of those that occur on the given segment exactly once. Help Sasha solve this problem.
Input
The first line contains two positive integers n and k (1 ≤ n ≤ 105, 1 ≤ k ≤ n) — the number of array elements and the length of the segment.
Then follow n lines: the i-th one contains a single number a i ( - 109 ≤ a i ≤ 109).
Output
Print n–k + 1 numbers, one per line: on the i-th line print of the maximum number of those numbers from the subarray a i a i + 1 … a i + k - 1 that occur in this subarray exactly 1 time. If there are no such numbers in this subarray, print “Nothing”.
Examples
Input
5 3
1
2
2
3
3
Output
1
3
2
Input
6 4
3
3
3
4
4
2
Output
4
Nothing
3

题意:给你一组数据,并给你一个数k,让你求从第一个数开始,每k个连续的数中出现一次的最大的那个数,如果没有输出Nothing。
思路:“出现一次“就想到STL中的set集合,但是当时没想到multiset集合,把k个数存到multiset里,判断出现一次的存到set里,遍历判断输出即可。
代码如下:

#include<iostream>
#include<cstdio>
#include<set>
using namespace std;
const int maxn=1e5+8;
set<int> one;
multiset<int> cur;
int main()
{
	int n,k;
	int a[maxn];
	cin>>n>>k;
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
	}
	for(int i=1;i<=k;i++)
	{
		int t=a[i];
		if(!cur.count(t))//cur集合中已有又出现,那就不是1个 
			one.insert(t);
		else
		    one.erase(t);
		cur.insert(t);
	}
	if(!one.size())
	cout<<"Nothing"<<endl;
	else
	cout<<*--one.end()<<endl;
	for(int i=k+1;i<=n;i++)
	{
		multiset<int>::iterator pos;
	    pos=cur.find(a[i-k]);//向后移动一个位置,去包含下一个k个元素 
		cur.erase(pos);
		if(!cur.count(a[i-k])&&one.count(a[i-k]))//看看删除了第一个元素会对当前k个数有什么影响 
		one.erase(a[i-k]);
		else if(cur.count(a[i-k])==1&&!one.count(a[i-k]))
		one.insert(a[i-k]);
		if(!cur.count(a[i]))
		one.insert(a[i]);
		else
		one.erase(a[i]);
		cur.insert(a[i]);
		if(!one.size())
		cout<<"Nothing"<<endl;
		else
		cout<<*--one.end()<<endl;
	}
	return 0;
}

C++ set集合常用操作(multiset):
(s为所定义的set集合)

s.insert(); 插入数
s.count(x); 返回集合中数x的个数
s.find(x); 查找函数,找到k返回迭代器位置没找到返回s.end()
s.erase(); 删除一个元素
s.begin(); 返回set容器的第一个元素。
s.end(); 返回set容器的最后一个元素的下一个位置。
s.clear(); 删除set容器中的所有的元素。
s.empty(); 判断set容器是否为空。
s.max_size(); 返回set容器可能包含的元素最大个数。
s.size(); 返回当前set容器中的元素个数。
s.rbegin(); 返回set容器的最后一个元素。
s.rend(); 返回set容器的第一个元素的前一个位置。

参考:https://www.cnblogs.com/xiaofengqaq/p/11314037.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值