STL一些笔记

1.set

关于set,必须说明的是set关联式容器。set作为一个容器也是用来存储同一数据类型的数据类型,并且能从一个数据集合中取出数据,在set中每个元素的值都唯一,而且系统能根据元素的值自动进行排序。

#include
set<类型> 变量名
//s.end()没有值,指向最后一个元素的后一个位置
set中关于clear和erase的一些用法

为何每次insert之后,以前保存的iterator不会失效?

 iterator这里就相当于指向节点的指针,内存没有变,指向内存的指针怎么会失效呢(当然被删除的那个元素本身已经失效了)。相对于vector来说,每一次删除和插入,指针都有可能失效,调用push_back在尾部插入也是如此。因为为了保证内部数据的连续存放,iterator指向的那块内存在删除和插入过程中可能已经被其他内存覆盖或者内存已经被释放了。即使时push_back的时候,容器内部空间可能不够,需要一块新的更大的内存,只有把以前的内存释放,申请新的更大的内存,复制已有的数据元素到新的内存,最后把需要插入的元素放到最后,那么以前的内存指针自然就不可用了。特别时在和find等算法在一起使用的时候,牢记这个原则:不要使用过期的iterator。

在这里插入图片描述

题解:
两个人轮流说出一个自己的单词,但是不能说出以及说出的单词,说不出单词的人输掉比赛
如果没有交集,n>m就是第一个人获胜
如果有交集:找出相同的单词k,
把单词都放入set中去重

显然两个人都肯定先争取中间重复那段先拿;
每个人每次只能拿一个单词;
则为奇数的话对第一个人来说有利;
然后去掉重复的中间那段;
设去掉重复后两人的单词量为x,y
则如果之前重复个数为奇数
x=x+1;
偶数的话则不用做处理;
然后比较x,y;
(第一个人能最多说出单词x= n-k+(k+1)/2, 第二个人能最多说出单词 y=m-k+k/2)
相同的话是第一个人输,
因为每次第一个人拿完之后,第二个人都比第一个人的单词量多;

类型:博弈+贪心?+stl

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
#include<set>
#include<cstring>
#include<iostream>
using namespace std;
int main(){
    
    
	int n,m;
	string s;
	set<string> st;
	cin>>n>>m;
	int i,j;
	for(i=0;i<n+m;i++){
    
    
		cin>>s;
		
		st.insert(s);
	}
	int k=n+m-st.size();
	int x=n-k+(k+1)/2,y=m-k+k/2;
	
	if(x>y)
	printf("YES\n");
	else
	printf("NO\n");
	
}

2.multiset

multiset 是关联容器的一种,是排序好的集合(元素已经进行了排序),并且允许有相同的元素。

不能直接修改 multiset 容器中元素的值。因为元素被修改后,容器并不会自动重新调整顺序,于是容器的有序性就会被破坏,再在其上进行查找等操作就会得到错误的结果。因此,如果要修改 multiset 容器中某个元素的值,正确的做法是先删除该元素,再插入新元素。

和所有的标准关联容器类似,sets和multisets通常以平衡二叉树完成。

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

自动排序的主要优点在于使二叉树搜寻元素具有良好的性能,在其搜索函数算法具有对数复杂度。但是自动排序也造成了一个限制,不能直接改变元素值,因为这样会打乱原有的顺序,要改变元素的值,必须先删除旧元素,再插入新元素。所以sets和multisets具有以下特点:

不提供直接用来存取元素的任何操作元素
通过迭代器进行元素的存取。

在这里插入图片描述
题解:
这个题实际上就是一个求交集的问题。

可以采用数组排序后比较来实现,也可以用STL实现。这里采用前一种方法实现,排序比较再做一下简单的计算就可以了。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
#include<set>
#include<cstring>
#include<iostream>
#define N 10020
int a[N],b[N];
using namespace std;
int main(){
    
    
	int t,n,m;
	
	int i,j;
	cin>>t;
	

	while(t--){
    
    
		cin>>n>>m;
		for(i=0;i<n;i++){
    
    
			cin>>a[i];
			
		}
		for(i=0;i<m;i++){
    
    
			cin>>b[i];
		
		}
		sort(a,a+n);
		sort(b,b+m);
		i=0,j=0;
		int cnt=0;
		while(i<n&&j<m){
    
    
			if(a[i]==b[j]){
    
    
				i++,j++,cnt++;
			}else if(a[i]<b[j]){
    
    
				i++;
			}else{
    
    
				j++;
			}
		}
		printf("%d\n",n+m-2*cnt);
		
	}
	
}


#include <cstdio>
#include <set>
#include <cstdlib>
 
using namespace std;
 
int n, m;
multiset<int> s1, s2;
 
void input()
{
    
    
	s1.clear();
	s2.clear();
	
	int num;
	scanf("%d%d", &n, &m);
	for (int i = 0; i < n; i++) {
    
    
		scanf("%d", &num);
		s1.insert(num);
	}
	
	for (int i = 0; i < m; i++) {
    
    
		scanf("%d", &num);
		s2.insert(num);
	}
}
 
void solve()
{
    
    
	int ans = 0;
	int prev;
	for (multiset<int>::iterator it = s2.begin(); it != s2.end(); it++) {
    
    
		if (it == s2.begin()) prev = *it;
		else if (*it == prev) continue;
		
		if (s1.count(*it)) {
    
    
			ans += abs((int)(s1.count(*it) - s2.count(*it)));
			s1.erase(*it);
		} else {
    
    
			ans += s2.count(*it);
		}
		
		prev = *it;
	}
	
	ans += s1.size();
	
	printf("%d\n", ans);
}
 
int main()
{
    
    
	#ifndef ONLINE_JUDGE
		freopen("d:\\OJ\\uva_in.txt", "r", stdin);
	#endif
	
	int t;
	scanf("%d", &t);
	for (int i = 1; i <= t; i++) {
    
    
		input();
		solve();
	}
	return 0;
}

//获得两个set的并
 36     set<int> eg3;
 37     cout << "Union(两个set的并集):";
 38     set_union(eg1.begin(),
 39         eg1.end(),
 40         eg2.begin(),
 41         eg2.end(),
 42         insert_iterator<set<int> >(eg3, eg3.begin())
 43         );//注意第五个参数的形式
 44     copy(eg3.begin(), eg3.end(), ostream_iterator<int>(cout, " "));
 45     cout << endl;
 46 
 47     //获得两个set的交,注意进行集合操作之前接收结果的set要调用clear()函数清空一下
 48     eg3.clear();
 49     set_intersection(eg1.begin(),
 50         eg1.end(),
 51         eg2.begin(),
 52         eg2.end(),
 53         insert_iterator<set<int> >(eg3, eg3.begin())
 54         );
 55     cout << "Intersection:";
 56     copy(eg3.begin(), eg3.end(), ostream_iterator<int>(cout, " "));
 57     cout << endl;
 58 
 59     //获得两个set的差
 60     eg3.clear();
 61     set_difference(eg1.begin(),
 62         eg1.end(), eg2.begin(),
 63         eg2.end(),
 64         insert_iterator<set<int> >(eg3, eg3.begin())
 65         );
 66     cout << "Difference:";
 67     copy(eg3.begin(), eg3.end(), ostream_iterator<int>(cout, " "));
 68     cout << endl;
 69 
 70     //获得两个set的对称差,也就是假设两个集合分别为A和B那么对称差为AUB-A∩B
 71     eg3.clear();
 72     set_symmetric_difference(eg1.begin(), eg1.end(), eg2.begin(), eg2.end(), insert_iterator<set<int> >(eg3, eg3.begin()));
 73     copy(eg3.begin(), eg3.end(), ostream_iterator<int>(cout, " "));
 74     cout << endl;
 75 

猜你喜欢

转载自blog.csdn.net/weixin_46064382/article/details/109558817