• 2020 camp day-5-A


    题解

    彩笔只会模拟

    k<=2直接输出做多那场的人数

    k==3

    先对三场比赛按账号数从高到低排序,则ans>=s[1][0]

    然后考虑 使++ans的情况,

    对于 第二场(排过序的)人数小于等于第一场 s[1][0]<=s[2][0],

    把第二场中第一场出现过的删去(并查集),第二场剩下的账号可以是第一场中未在第二场出现的人的,

    如果 剩下人数>第一场未在第二场中出现的人数 则 ans+=人数差

    对于第三场,讨论较多

    1:先删除第一场出现第二场未出现的,第一场出现第二场未出现第三场出现的账号可以和只在第二场出现的账号 是同一个人的

    2:只在第一场出现的可以和只在第二场出现的账号是同一个人的

    3:在第一场出现不出现在第三场的可以和只在第三场出现的账号是同一个人

    对每种情况判断是否无法将两个账号归于一人,则++ans

    #include <cstdio>
    #include <vector>
    #include <algorithm>
    #include <cstring>

    #define RE register
    #define FOR(i,a,b) for(RE int i=a;i<=b;++i)
    #define ROF(i,a,b) for(RE int i=a;i>=b;--i)
    #define sc(n) scanf("%d",&n)
    #define ll long long
    #define db double
    //#define p pair<int,int>

    using namespace std;

    const int maxn = 1e5 + 5;

    int m, n, k, x, y;
    vector<int> s[4];

    const static int MAX_V = 1e5 + 5;
    int f[MAX_V], high[MAX_V], dis[MAX_V], E, V, d[MAX_V], num[MAX_V];
    int vis[maxn], v[maxn];

    int find(int x)
    {
        if (f[x] != x)return f[x] = find(f[x]);
        return f[x];
    }

    bool same(int x, int y)
    {
        int fx = find(x), fy = find(y);
        return fx == fy;
    }

    void unit(int x, int y)
    {
        int fx = find(x), fy = find(y);
        if (x == y)return;
        if (high[fx] > high[fy])f[fy] = fx;
        else if (high[fx] < high[fy])f[fx] = fy;
        else f[fy] = fx, ++high[fx];
    }

    bool cmp(const vector<int> a, const vector<int> b)
    {
        return a.size() > b.size();
    }

    int main()
    {
        sc(n); sc(k);
        FOR(i, 1, n)f[i] = i, high[i] = 1;
        FOR(i, 1, k)
        {
            sc(m);
            s[i].push_back(m);
            FOR(j, 1, s[i][0])sc(m), s[i].push_back(m);
        }
        sort(s + 1, s + 1 + k, cmp);
        if (k <= 2)
        {
            printf("%d", s[1][0]);
            return 0;
        }
        x = s[1][0];
        FOR(i, 2, s[1][0])unit(s[1][1], s[1][i]);
        int flag = 0;
        FOR(i, 1, s[2][0])
        {
            if (same(s[1][1], s[2][i]))
            {
                --x;
                f[s[2][i]] = s[2][i];
            }
            else
            {
                ++y;
                if (!flag)flag = s[2][i];
                else unit(flag, s[2][i]);
            }
        }
        if (!y)
        {
            printf("%d", s[1][0]);
            return 0;
        }
        int ans = s[1][0], x1 = 0, yy1 = y;
        FOR(i, 1, s[3][0])
        {
            if (same(s[1][1], s[3][i]))++x1;
            else if (same(flag, s[3][i]))--yy1;
        }
        int sb = yy1 - x1;
        if (sb < 0)sb = 0;
        sb = sb + y - yy1 - x + x1;
        if (sb < 0)sb = 0;
        ans += sb;
        if (sb < 0)sb = 0;
        sb = - x1 - y + yy1 + s[1][0];
        if (sb < 0)sb = 0;
        sb = s[3][0] - x1 - y + yy1 - sb;
        if (sb < 0)sb = 0;
        ans += sb;
        printf("%d", ans);
        return 0;
    }
  • 相关阅读:
    数据结构 【实验 串的基本操作】
    Ioc容器依赖注入-Spring 源码系列(2)
    定时任务管理中心(dubbo+spring)-我们到底能走多远系列47
    jvm内存增长问题排查简例
    Ioc容器beanDefinition-Spring 源码系列(1)
    SPI机制
    java工厂-积木系列
    java单例-积木系列
    利用spring AOP 和注解实现方法中查cache-我们到底能走多远系列(46)
    java 静态代理-积木系列
  • 原文地址:https://www.cnblogs.com/2aptx4869/p/12203290.html
Copyright © 2020-2023  润新知