zoukankan      html  css  js  c++  java
  • 【Henu ACM Round#20 D】 Devu and Partitioning of the Array

    【链接】 我是链接,点我呀:)
    【题意】

    在这里输入题意

    【题解】

    一开始所有的数字单独成一个集合。 然后用v[0]和v[1]记录**集合的和**为**偶数**和**奇数**的集合**它们的根节点**(并查集

    然后先让v[0]的大小变成p

    //奇数+偶数是奇数
    //奇数+奇数是偶数
    //偶数+偶数是偶数

    如果v[0].size < p
    那么随便让两个和为奇数的集合,让他们合并在一起,加入到偶数集合中,那么v[0].size++,v[1].size-=2了

    如果v[0].size > p
    那么有两种方法
     1.让两个偶数集合合并在一起,变成一个更大的偶数集合,v[0].size()--
     2.让一个偶数集合和一个奇数集合合并在一起,变成一个奇数集合,v[0].size()--,但是奇数集合个数还是不变

    此后v[0].size==p了

    那么接下来只要调整v[1].size就好了
    但是在调整之前先判断v[0].size()+v[1].size()>=k是否成立

    如果小于k的话,是肯定没办法变多的。
    因为越并只能越少的

    然后如果大于k的话,只能把v[1]的大小变小了。
    根据上面奇数和偶数相加的规则。
    不难发现。
    只能把两个奇数合并成偶数才能减少奇数的个数。
    且显然奇数只能两个两个地减少。
    减少的过程如下
    1.把两个奇数合并成1个偶数。
    2.把新合成的那个偶数去掉
     有两种去掉的方法
       ①用两个偶数集合合成一个新的偶数集合
       ②再用一个奇数和这个偶数,合成一个奇数集合

    最后看看v[0].size()+v[1].size()是否等于k就好。
    最后根据并查集的根节点。
    输出每个集合里面的元素就好。

    【代码】

    #include <bits/stdc++.h>
    using namespace std;
    
    
    
    //������������ж��ٸ���ż���ж��ٸ�
    //����+ż��������
    //����+������ż��
    //ż��+ż����ż��
    //������û��p��ż��
    //���û�еĻ�
    // ����������һ��ż��
    
    const int N = 1e5;
    
    int n,k,p;
    int f[N+10],a[N+10];
    vector<int> v[2];
    vector<int> bo[N+10];
    
    int ff(int x){
        if (f[x]==x)
            return x;
        else
            return f[x] = ff(f[x]);
    }
    
    int qu(int idx){
        int x = v[idx].back();
        v[idx].pop_back();
        return x;
    }
    
    int main()
    {
        ios::sync_with_stdio(0),cin.tie(0);
        cin >> n >> k >> p;
    
        for (int i = 1;i <= n;i++){
            cin >> a[i];
            v[a[i]%2].push_back(i);
        }
        for (int i = 1;i <= n;i++) f[i] = i;
    
    
        while ((int)v[0].size()<p){
            if ((int)v[1].size()>=2){
                int x = qu(1),y = qu(1);
                int r1 = ff(x),r2 = ff(y);
                f[r1] = r2;
                v[0].push_back(r2);
            }else{
                return cout<<"NO"<<endl,0;
            }
        }
        //a[0] >= p
        while ((int)v[0].size()>p){
            if ((int)v[0].size()>1){
                int x = qu(0),y = qu(0);
                int r1 = ff(x),r2 = ff(y);
                f[r1] = r2;
                v[0].push_back(r2);
                continue;
            }
            if ((int)v[1].size()>0){
                int x = qu(1);
                int y = qu(0);
                int r1 = ff(x),r2 = ff(y);
                f[r1]=r2;
                v[1].push_back(r2);
            }else return cout<<"NO"<<endl,0;
        }
    
        //a[0]==p
        if ((int)v[0].size()+(int)v[1].size()<k){
            return cout<<"NO"<<endl,0;
        }
    
    //����+ż��������
    //����+������ż��
    //ż��+ż����ż��
        while ((int)v[0].size()+(int)v[1].size()>k){
            if ((int)v[1].size()>=2){
                int x = qu(1),y = qu(1);
                int r1 = ff(x),r2 = ff(y);
                f[r1] = r2;
                v[0].push_back(r2);
            }else{
                return cout<<"NO"<<endl,0;
            }
            if ((int)v[0].size()>1){
                int x = qu(0),y = qu(0);
                int r1 = ff(x),r2 = ff(y);
                f[r1] = r2;
    
                v[0].push_back(r2);
            }else if ((int)v[0].size()>0 && (int)v[1].size()>0){
                int x = qu(0),y = qu(1);
                int r1 = ff(x),r2 = ff(y);
                f[r1] = r2;
                v[1].push_back(r2);
            }else return cout<<"NO"<<endl,0;
        }
    
        if ((int)v[0].size()+(int)v[1].size()<k){
            cout<<"NO"<<endl;
            return 0;
        }
    
        cout<<"YES"<<endl;
        for (int i = 1;i <= n;i++){
            int r = ff(i);
            bo[r].push_back(i);
        }
    
        for (int i = 1;i <= n;i++)
            if (!bo[i].empty()){
                cout<<(int)bo[i].size()<<' ';
                for (int x:bo[i]){
                    cout<<a[x]<<' ';
                }
                cout<<endl;
            }
        //a[0]==p
        return 0;
    }
    
  • 相关阅读:
    echarts
    联合省选2021游记
    高维 FWT 学习笔记
    Unicode简介
    mac安装brew
    原生JS实现分页跳转
    Kubernetes Pod Probes 探针解析
    Kubernetes Secrets
    Kubernetes Container lifecycle hooks
    个人作业1——四则运算题目生成程序(基于java)
  • 原文地址:https://www.cnblogs.com/AWCXV/p/8404347.html
Copyright © 2011-2022 走看看