給定兩個嚴格遞增排序的整數集合 A、B(元素數 1~30000,值為 32 位帶號整數),求:
輸出格式:每組測試資料 5 行,第 1 行案例編號,後 4 行依序輸出上述四集合,元素以空格分隔,空集輸出空行。
利用兩集合**已排序**特性,雙指標同步掃描:
*pa == *pb → 屬於交集,雙指標後移。*pa < *pb → *pa 僅屬 A,併入並集與 A-B,pa++。*pa > *pb → *pb 僅屬 B,併入並集與 B-A,pb++。#include <cstdio>
#include <cstdlib>
#include <vector>
using namespace std;
struct SqList {
vector elem; // 用 vector 替代手動 malloc/realloc
int length = 0;
};
void readList(SqList& L, int n) {
L.elem.resize(n);
for (int i = 0; i < n; ++i) scanf("%d", &L.elem[i]);
L.length = n;
}
void merge(const SqList& A, const SqList& B,
vector& inter, vector& uni,
vector& aMinusB, vector& bMinusA) {
int i = 0, j = 0;
while (i < A.length && j < B.length) {
if (A.elem[i] == B.elem[j]) {
inter.push_back(A.elem[i]);
uni.push_back(A.elem[i]);
++i; ++j;
} else if (A.elem[i] < B.elem[j]) {
uni.push_back(A.elem[i]);
aMinusB.push_back(A.elem[i]);
++i;
} else {
uni.push_back(B.elem[j]);
bMinusA.push_back(B.elem[j]);
++j;
}
}
while (i < A.length) {
uni.push_back(A.elem[i]);
aMinusB.push_back(A.elem[i]);
++i;
}
while (j < B.length) {
uni.push_back(B.elem[j]);
bMinusA.push_back(B.elem[j]);
++j;
}
}
void printVec(const vector& v) {
for (size_t i = 0; i < v.size(); ++i) {
if (i) putchar(' ');
printf("%d", v[i]);
}
putchar('\n');
}
int main() {
int T; scanf("%d", &T);
for (int tc = 1; tc <= T; ++tc) {
SqList A, B;
int na, nb;
scanf("%d", &na); readList(A, na);
scanf("%d", &nb); readList(B, nb);
vector inter, uni, aMinusB, bMinusA;
merge(A, B, inter, uni, aMinusB, bMinusA);
printf("Case #%d:\n", tc);
printVec(inter);
printVec(uni);
printVec(aMinusB);
printVec(bMinusA);
}
return 0;
}
malloc/realloc,安全簡潔。unordered_set O(n) 平均。set_intersection、set_union、set_difference 直接對應四操作,生產碼優先使用。