本文主要是介绍FDU 2018 | 2. 集合交并,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
文章目录
- 1. 题目描述
- 2. 我的尝试
- 1. C++容器
- 2. 排序+二路归并
1. 题目描述
AcWing 3688 集合交并
输入两个集合,分别求其交集和并集中元素的个数,每个集合中可能存在相同的元素,而最终的交集和并集中应该不存在。
输入格式
第一行输入两个整数 n,m 表示两个集合中元素的个数。
第二行输入 n 个整数,表示第一个集合中的元素。
第三行输入 m 个整数,表示第二个集合中的元素。
输出格式
输出两个整数以空格分开,表示其交集和并集中元素的个数。
数据范围
1 ≤ n , m ≤ 1 0 5 1≤n,m≤10^5 1≤n,m≤105, 给定集合元素取值范围 [ 1 , 1 0 9 ] [1,10^9] [1,109]。
输入样例
4 5
3 4 7 3
4 6 3 2 6
输出样例
2 5
2. 我的尝试
1. C++容器
考察set
基础用法
#include<stdio.h>
#include<string.h>
#include<string>
#include<set>
#include<algorithm>
#include<iterator>
using namespace std;
set<int> a, b, c, d;
int n, m, x;
int main()
{scanf("%d%d", &n, &m);for (int i = 1; i <= n; ++i)scanf("%d", &x), a.insert(x);for (int i = 1; i <= m; ++i)scanf("%d", &x), b.insert(x);set_intersection(a.begin(), a.end(), b.begin(), b.end(), inserter(c, c.begin()));set_union(a.begin(), a.end(), b.begin(), b.end(), inserter(d, d.begin()));printf("%d %d", c.size(), d.size());
}
2. 排序+二路归并
分别用两个数组来存两个集合并对其排序(此时未去重),排序后用类似二路归并的方法得到找到同时在两集合中出现的元素,得到交集(已去重)。并集元素个数可以用原始两集合元素的个数和减去交集元素个数得到。
#include <bits/stdc++.h>using namespace std;const int N = 1e5 + 10;
int a[N], b[N];
vector<int> r;int main()
{int n, m;int cnt1 = 0, cnt2 = 0;cin >> n >> m;for (int i = 0; i < n; i ++) scanf("%d", &a[i]);for (int i = 0; i < m; i ++) scanf("%d", &b[i]);sort(a, a + n);sort(b, b + m);for (int i = 0; i < n; i++)if (i == 0 || a[i] != a[i - 1]) cnt1++;for (int j = 0; j < m; j++)if (j == 0 || b[j] != b[j - 1]) cnt2++;int i = 0, j = 0;while (i < n && j < m){if (a[i] < b[j]){i ++;while (i == 0 || (i < n && a[i] == a[i-1])) i++;if (i == n - 1 && a[i] == b[i-1]) break;}else if (b[j] < a[i]){ j ++;while (j == 0 || (j < m && b[j] == b[j-1])) j++;if (j == m - 1 && b[j] == b[j-1]) break;}else {r.push_back(a[i]);i++, j++;while (i == 0 || (i < n && a[i] == a[i-1])) i++;while (j == 0 || (j < m && b[j] == b[j-1])) j++;}}cout << r.size() << " " << cnt1 + cnt2 - r.size();
}
这篇关于FDU 2018 | 2. 集合交并的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!