给出两个由数字组成的集合,请求这两个集合的“交”和“并”。
输入格式:
给一个n,m 代表两个数列的大小 (0 <= n,m <=2e5)
如果n>0,则接下来一行, n个数空格隔开,代表第一个集合中的数。
如果m>0,则接下来一行, m个数空格隔开,代表第二个集合中的数。
-1e9<=ai,bi<=1e9
输出格式:
第一行首先输出两个数列交的集合中元素个数,如果元素个数大于0,则紧接着在这行输出“交集”的元素,按数值大小升序排列(本行输出多个数据时,用空格隔开,如果只有一个元素个数,行末无空格)
第二行首先输出两个数列并的集合中元素个数,如果元素个数大于0,则紧接着在这行输出“并集”的元素,按数值大小升序排列(本行输出多个数据时,用空格隔开,如果只有一个元素个数,行末无空格)
输入样例1:
1 3
1
1 3 4
输出样例1:
1 1
3 1 3 4
输入样例2:
1 3
1
2 3 4
输出样例2:
0
4 1 2 3 4
题解
利用双指针,先对两个数组排序,求交集和并集都是从前向后遍历。交集输出相等的元素,并集求解时每次将两个数组中较小的元素放入并集答案,最后再把未遍历完整的数组加进去。
/*1.将数据读入vector v1 v2中
2.将v1,v2排序
3.双指针的方法记录交集值
4.用双指针,每一次将较小的放进并集
5.输出
*/
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
int main() {
int n, m, a = 0, b = 0;
cin >> n >> m;
vector<int> v1(n), v2(m), J, B;//J是交集,B是并集
for (int i = 0; i < n; i++) cin >> v1[i];
for (int i = 0; i < m; i++) cin >> v2[i];
sort(begin(v1), end(v1));
sort(begin(v2), end(v2));
while (a < n && b < m) {
if (v1[a] < v2[b]) {
B.push_back(v1[a]);
a++;
} else if (v1[a] > v2[b]) {
B.push_back(v2[b]);
b++;
} else {
J.push_back(v1[a]);
b++;
}
}
if (a==n) {
for (int b_temp=b; b_temp < m; b_temp++) B.push_back(v2[b_temp]);
} else {
for (int a_temp=a; a_temp < n; a_temp++) B.push_back(v1[a_temp]);
}
if (J.size()) {
cout << J.size();
for (auto temp : J) {
cout <<" "<< temp;
}
cout << endl;
} else {
cout << "0" << endl;
}
cout << B.size() ;
for (auto temp : B) {
cout <<" "<< temp ;
}
system("pause");
}
需要注意的是,PTA平台如果输出的空格不一致,就会造出格式错误,在循环时尤其要注意末尾是不是多加了空格,本题由于先输出了数组个数,循环时先输出空格即可,如果是一般题目,可以像下面这样。
如果输出内容有多行时候,通过循环结构实现输出很容易会多一个换行符。
for(i=1;i<=5;i++) printf("hello\n");
上面代码运行没任何问题,输出了5行hello
,但是最后一个hello
还会多了一个\n
,就是会换行。 但是多的这个换行符就会和题目要求输出不匹配,一般PTA题目输出多行内容,最后一行都没有换行符,所以这段代码提交还是会犯格式错误问题。怎么解决呢?
- 1.最后一项单独判断
for(i=1;i<=5;i++)
{
if(i==5) printf("hello");
else printf("hello\n");
}
- 2.最后一项不好确定,引入flag
int flag=1;
for(i=1;i<=5;i++)
{
if(flag) {printf("hello");flag=0;}
else printf("\nhello");
}
上述代码输出的5行hello
,就可以去掉尾部换行符
。还有尾部多空格符
,一样处理。你也可以根据题目具体输出要求修改你的程序。