速通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;
}

结语:

        今日算法讲解到此结束啦,希望对你们有所帮助,谢谢观看,如果觉得不错可以分享给朋友哟。有什么看不懂的可以评论问哦,这是真的最后一期啦

评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值