【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;
}
【Henu ACM Round#20 D】 Devu and Partitioning of the Array的更多相关文章
- 【Henu ACM Round#20 F】 Arthur and Brackets
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 所给的li,ri是左括号从左到右的顺序给的. (且注意长度是2*n 现在我们先把第一个左括号放在第1个位置. 然后考虑第二个位置. ...
- 【Henu ACM Round#20 E】Star
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 找规律. 1,13,37.... 6n(n-1) + 1 [代码] #include <bits/stdc++.h> # ...
- 【Henu ACM Round#20 C】 Eevee
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 处理处所有的字符串可能的样子. 存在map里面就好. [代码] #include <bits/stdc++.h> usi ...
- 【Henu ACM Round#20 B】Contest
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 根据时间和原分数. 算出对应的分数就可以了. [代码] #include <bits/stdc++.h> using n ...
- 【Henu ACM Round#20 A】 Fancy Fence
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 看看有没有(n-2)*180/n等于输入的a就好. [代码] #include <bits/stdc++.h> usin ...
- 【Henu ACM Round#15 F】Arthur and Questions
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] a1+a2+...+ak<a2+a3+...ak+1 ->a1<ak+1 a2+a3+...+ak+1<a3 ...
- 【Henu ACM Round#24 E】Connected Components
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 要求把连续的一段li..ri的边全都删掉. 然后求剩下的图的联通数 如果暴力的话 复杂度显然是O(k*m)级别的. 考虑我们把li. ...
- 【Henu ACM Round#24 D】Iterated Linear Function
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 把B提取出来就是一个等比数列了. 求和一下会发现是这种形式. \(B*\frac{(A^n-1)}{A-1}+A^n*x\) 则求一 ...
- 【Henu ACM Round#24 C】Quiz
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 肯定是这样 先放k-1个,然后空1个,然后再放k-1个.然后再空1个.. 以此类推. 然后如果(n/k)*(k-1)+n%k> ...
随机推荐
- 在Scrapy中如何利用Xpath选择器从HTML中提取目标信息(两种方式)
前一阵子我们介绍了如何启动Scrapy项目以及关于Scrapy爬虫的一些小技巧介绍,没来得及上车的小伙伴可以戳这些文章: 手把手教你如何新建scrapy爬虫框架的第一个项目(上) 手把手教你如何新建s ...
- NOIp模拟赛三十一
持续降智 分数:100+0+0=100 C题subtask是假的,根本没有部分分中的情况...还我20分QAQ A:[BZOJ4444]国旗计划 B:[agc006f]blackout C:[arc0 ...
- POJ-2240 Arbitrage BellmanFord查可循环圈
题目链接:https://cn.vjudge.net/problem/POJ-2240 题意 套利(Arbitrage)就是通过不断兑换外币,使得自己钱变多的行为 给出一些汇率 问能不能套利 思路 马 ...
- 【Python常见问题总结】
1. python2 中 end = '' 取消换行没有用 解决办法: 在程序开始加入 from __future__ import print_function 2. 如何在电脑上同时使用pytho ...
- Linux系统下安装配置 OpenLDAP + phpLDAPadmin
实验环境: 操作系统:Centos 7.4 服务器ip:192.168.3.41 运行用户:root 网络环境:Internet LDAP(轻量级目录访问协议)是一个能实现提供被称为目录服务的信息服务 ...
- 题解 P3372 【【模板】线段树1 】(zkw)
看了一下题解里的zkw线段树,感觉讲的不是很清楚啊(可能有清楚的但是我没翻到,望大佬勿怪). 决定自己写一篇...希望大家能看明白... zkw线段树是一种优秀的非递归线段树,速度比普通线段树快两道三 ...
- Myeclipse学习总结(8)——Eclipse实用操作
工欲善其事,必先利其器.对于程序员来说,Eclipse便是其中的一个"器".本文会从Eclipse快捷键和实用技巧这两个篇章展开介绍.Eclipse快捷键用熟后,不用鼠标,便可进行 ...
- Memcached存储溢出
Memcached存储溢出 测试数据生成程序: package com.stoon.test; public class TestFor { public static void main(Strin ...
- hdu 5277 YJC counts stars
hdu 5277 YJC counts stars 题意: 给出一个平面图,n个点,m条边,直线边与直线边之间不相交,求最大团的数目. 限制: 1 <= n <= 1000 思路: 因为平 ...
- Block的使用--初探Block
看了两天的Block. 网上是有非常多解说与教程,也有讲得非常好的.这里就主要解说下我的理解与收获.欢迎拍砖. 所谓block.我觉得应该是一个闭包函数.而闭包,就是说block以及内部全部的变量生命 ...