题目:
样例:
|
4 5 6 0 |
思路:
这里题目的意思是,要求合并尽可能多的集合,使它的集合大小最大,但是不能等于全部集合的合并。
这里由于题目所给的范围较小,所以我们可以暴力枚举,其次,里面也有贪心的成分,这里我们换个思路,我们通过总的集合,根据总的集合中的某个元素,枚举不存在该元素的集合,并合并,就是不等于全部集合的合并,取个合并后的集合个数 max,就是答案。
代码详解如下:
#include <iostream>
#include <vector>
#include <unordered_set>
#include <unordered_map>
#define endl '\n'
#define YES puts("YES")
#define NO puts("NO")
#define umap unordered_map
#define uset unordered_set
#pragma GCC optimize(3,"Ofast","inline")
#define ___G std::ios::sync_with_stdio(false),cin.tie(0), cout.tie(0)
using namespace std;
const int N = 2e6 + 10;inline void solve()
{ int t,ans = 0;umap<int,vector<int>>v; // 记录每个集合uset<int>sum; // 统计总集合cin >> t; // t 为集合个数for(int i = 1;i <= t;++i){int n; // 集合大小cin >> n; for(int j = 1;j <= n;++j){int x; // 集合元素cin >> x;// 记录该集合v[i].emplace_back(x);// 统计总集合元素sum.insert(x);}}// 开始 贪心删除for(auto now : sum){ // 选择删除后的合并集合uset<int>tem;for(int i = 1;i <= t;++i){// st 标记是否删除该集合bool st = false;// 遍历该集合for(auto j : v[i]){// 如果 sum 中的某个元素存在该集合// 那么我们选着的是删除这个集合// 所以无需添加if(now == j){st = true;break;}}// 如果该集合不用删除,那么我们就添加该集合的元素if(!st){for(auto j : v[i]) tem.insert(j);} }// 判断选择删除这个元素后的,所有集合大小// 选择答案 合并集合个数最大,但不等于 sum 集合ans = max(ans,(int)tem.size());}cout << ans << endl;
}int main()
{
// freopen("a.txt", "r", stdin);___G;int _t = 1;cin >> _t;while (_t--){solve();}return 0;
}