速通ACM省铜第二十一天(补) 赋源码(共现的数)
引言:
昨天以为是最后一天了,但没想到昨天想来想去感觉没问题的那道题,然后今天去看题解,发现竟然是因为数据有多组,我没注意到那个条件,只进行了一组数据的操作导致错了,真没招了
那么接下来,就进入今天的题目讲解啦——————————————>
共现的数
按照惯例,我们先来看题目
题目分析
题目如图
首先我们先看题目,首先给你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;
}
结语:
今日算法讲解到此结束啦,希望对你们有所帮助,谢谢观看,如果觉得不错可以分享给朋友哟。有什么看不懂的可以评论问哦,这是真的最后一期啦