引言:
昨天以为是最后一天了,但没想到昨天想来想去感觉没问题的那道题,然后今天去看题解,发现竟然是因为数据有多组,我没注意到那个条件,只进行了一组数据的操作导致错了,真没招了
那么接下来,就进入今天的题目讲解啦——————————————>

共现的数
按照惯例,我们先来看题目
题目分析
题目如图


首先我们先看题目,首先给你n个集合,然后再进行m次查询,每次查询俩个数,输出与这俩个数都共现的数有几个
那俩个数怎么算共现呢,很简单如果俩个数出现在同一个集合中,这俩个数就共现
那么题目的意思很简单,就这么点,那么接下来,我们进入逻辑梳理环节
逻辑梳理
既然意思知道了,其实这题也很简单了,我们需要找到与2个数共同共现的数,那么我们只需要将每个数共现的数找出来,然后如果共现的数是一样的,就++,若不一样,就接着往下找就好了,然后还有因为有多次数组,所以不能少了每次的数组重置操作,那只需要创一个数组来判断有没有访问过,再来俩个数组来装俩个分别共数
代码实现
这里就直接上AC码啦
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string.h>
#include <algorithm>
#include <queue>
using namespace std;
int vis[60][10010];
int visx[10010];
int visy[10010];
int main()
{
int n;
while (cin >> n)
{
memset(vis, 0, sizeof(vis));
memset(visy, 0, sizeof(visy));
memset(visx, 0, sizeof(visx));
vector<int> p[60];
for (int i = 1; i <= n; i++)
{
int m;
cin >> m;
for (int j = 1; j <= m; j++)
{
int k;
cin >> k;
vis[i][k] = 1;
p[i].push_back(k);
}
}
int q;
cin >> q;
int x, y;
for (int i = 1; i <= q; i++)
{
long long ans = 0;
memset(visx, 0, sizeof(visx));
memset(visy, 0, sizeof(visy));
cin >> x >> y;
for (int i = 1; i <= n; i++)
{
if (vis[i][x] && vis[i][y])
{
for (int j = 0; j < p[i].size(); j++)
{
visx[p[i][j]] = 1;
visy[p[i][j]] = 1;
}
}
else if (vis[i][x])
{
for (int j = 0; j < p[i].size(); j++)
{
visx[p[i][j]] = 1;
}
}
else if (vis[i][y])
{
for (int j = 0; j < p[i].size(); j++)
{
visy[p[i][j]] = 1;
}
}
}
for (int i = 1; i <= 10000; i++)
{
if (visx[i] && visy[i] && i != x && i != y)
ans++;
}
cout << ans << endl;
}
}
return 0;
}
结语:
今日算法讲解到此结束啦,希望对你们有所帮助,谢谢观看,如果觉得不错可以分享给朋友哟。有什么看不懂的可以评论问哦,这是真的最后一期啦







