CSU1409: 集合的并
Description
给出两个由整数组成的集合A, B,计算A ∪ B中包含多少个整数。
Input
输入的第一行包含一个整数T (T > 0),表示一共有T组测试数据。
对于每组测试数据,第一行包含一个整数n (1 ≤ n ≤ 105)。第二行包含2n个整数a1, b1, a2, b2, ..., an, bn (0 < a1 ≤ b1 < a2 ≤ b2 < ... < an ≤ bn < 109),表示A = [a1, b1] ∪ [a2, b2] ∪ ... ∪ [an, bn]。第三行包含一个整数m (1 ≤ m ≤ 105)。第四行包含2m个整数c1, d1, c2, d2, ..., cm, dm (0 < c1 ≤ d1 < c2 ≤ d2 < ... < cm ≤ dm < 109),表示B = [c1, d1] ∪ [c2, d2] ∪ ... ∪ [cm, dm]。
这里[x, y]表示由x, y之间(包含x, y)所有整数组成的集合。
Output
对于每组测试数据,输出A ∪ B中包含多少个整数。
Sample Input
3
1
7 7
1
3 3
2
1 2 3 4
1
2 3
2
1 2 4 6
3
1 3 6 7 9 10
Sample Output
2
4
9
HINT
对样例1的解释:A = {7},B = {3},A ∪ B = {3, 7}。
对样例2的解释:A = {1, 2, 3, 4},B = {2, 3},A ∪ B = {1, 2, 3, 4}。
对样例3的解释:A = {1, 2, 4, 5, 6},B = {1, 2, 3, 6, 7, 9, 10},A ∪ B = {1, 2, 3, 4, 5, 6, 7, 9, 10}。
这题刚开始只看到了10的5次方,没看到后面还有一个10的9次方。就去敲代码后提交。直接RE因为内存开小了,后来看清题目去改大内存然后直接内存超限。然后去网上搜了一下解题报告,最初一看好熟悉的,sort结构体排序,加上计算单个区间和长度。好好熟悉的。
然后就开始敲代码,因为上次有人说过一个类似的题目,当时顺便看了一下c++中的sort排序特别是sort结构体排序,因此先说一下sort结构体排序;
C++中的sort函数的头文件是#include<algorithm>;
sort函数的三个参数
第一个;开始值的地址
第二个;结束值的地址
第三个;排序的函数,若没有则默认为升序排列;记住函数return中大于为降序,小于为升序。
现在说对结构体数组的排序;
#include<iostream>
#include<algorithm>
using namespacestd;
struct node
{
int a;
int b;
double c;
}arr[100];
bool cmp(node x, node y)//要定义成bool形
{
if(x.a !=y.a) return x.a < y.b;
if(x.b != y.b) return x.b > y.b;
return x.c > y.c;
}//先根据a升序排列若相等则根据b来降序排列 否则 按照c降序排列;
sort(arr, arr+90,cmp);//直接加+90而不是作为下标,
正如代码;
定义bool函数,形参为结构体变量,用结构体变量元素来排序;
现在我们再来分析题目;
简化就是很多集合求他们的并集中的整数个数;有点注意的是一个集合也就是一个范围,并且是一个连续整数的范围;则这个集合内的整数个数就是end-st+1;
现在再看我们知道很多集合了,要怎么统计他们呢。集合与集合之间还有重复的,记得原来做过一道类似的,这就要用到排序的问题了。将集合的st按升序排列,若相同按照end降序排列;这里就需要上面的sort排列了。
再怎么计算呢;;剩下的就简单了,按顺序排列好了后在就是计算每个集合的,这里有个小技巧要自己注意。
看代码;
#include<iostream>
#include<stdio.h>
#include<algorithm>
using namespace std;//因为要用sort所以要用到 c++;
struct jh
{
long long int a;
long long int b;
}zs[200008];//所有集合都用zs表示;
bool cmp(jh l, jh m)
{
if(l.a == m.a)return l.b > m.b;//结构体按照b元素的降序排列;
return l.a < m.a;//结构体按照a元素的升序排列。
}
int main()
{
long long int n, sz, sb, sa, st, count, i;
scanf("%lld",&n);
while(n--){
scanf("%lld",&sa);
for(i = 0; i < sa; i++){
scanf("%lld %lld",&zs[i].a, &zs[i].b);
}
scanf("%lld",&sb);
for(i = sa; i < sa+sb; i++){
scanf("%lld %lld",&zs[i].a, &zs[i].b);
}
sort(zs,zs+sa+sb,cmp);
st = 0;
count = 0;
for(i = 0; i < sa+sb; i++){
if(zs[i].a >= st)st = zs[i].a;
if(zs[i].b >= st){
count += zs[i].b-st+1;
st = zs[i].b+1;
}
}
printf("%lld\n",count);
}
return 0 ;
}