zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    袁创:如何成为黄金程序猿
    划重点!新版电子病历评级标准讲解会上6大核心要点
    台湾医院信息化见闻录
    2500行代码实现高性能数值表达式引擎
    HIT创业感言:只有长寿的企业才有持续价值
    袁创:寂静的战争
    相约南湖,南京都昌信息亮相南湖HIT论坛
    我们是谁?南京都昌信息科技有限公司!
    医疗链的系列谈 第一篇 基本概念研究
    论电子病历控件的现状和发展方向
  • 原文地址:https://www.cnblogs.com/2aptx4869/p/12203290.html
Copyright © 2011-2022 走看看