【codeofrces 722D】【贪心 STL维护】D. Generating Sets 【X集合的数 可以有两种方式变换Y 现在给你一个集合Y 求X 且这个X的里最大的数尽可能小】
2016-10-02 17:12
639 查看
传送门:D. Generating Sets
描述:
D. Generating Sets
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
You are given a set Y of n distinct positive
integers y1, y2, ..., yn.
Set X of n distinct positive
integers x1, x2, ..., xn is
said to generate set Y if one can transform X to Y by
applying some number of the following two operation to integers in X:
Take any integer xi and
multiply it by two, i.e. replace xi with 2·xi.
Take any integer xi,
multiply it by two and add one, i.e. replace xi with 2·xi + 1.
Note that integers in X are not required to be distinct after each operation.
Two sets of distinct integers X and Y are
equal if they are equal as sets. In other words, if we write elements of the sets in the array in the increasing order, these arrays would be equal.
Note, that any set of integers (or its permutation) generates itself.
You are given a set Y and have to find a set X that
generates Y and the maximum element of X is
mininum possible.
Input
The first line of the input contains a single integer n (1 ≤ n ≤ 50 000) —
the number of elements in Y.
The second line contains n integers y1, ..., yn (1 ≤ yi ≤ 109),
that are guaranteed to be distinct.
Output
Print n integers — set of distinct integers that generate Y and
the maximum element of which is minimum possible. If there are several such sets, print any of them.
Examples
input
output
input
output
input
output
题意:
X集合的数 可以有两种方式变换Y 现在给你一个集合Y 求X 且这个X的里最大的数 尽可能小
注意原数列和目标数列都必须满足set内元素的性质(即每个元素都不相同),但是在变化的过程中不需要满足这个条件。
思路:
贪心,每次取出最大的数字,除以2,如果没有重复元素的话就结束(也就是说不必一次就把它除到最小)并且放回集合里面,一直这样操作直到最大的数字无法变化为止。这样的贪心思路才是正确的。
代码一:
(堆来维护)
//G++ 327ms 21300k
#include <bits/stdc++.h>
#define pr(x) cout << #x << "= " << x << " " ;
#define pl(x) cout << #x << "= " << x << endl;
#define ll __int64
using namespace std;
template<class T> void read(T&num) {
char CH; bool F=false;
for(CH=getchar();CH<'0'||CH>'9';F= CH=='-',CH=getchar());
for(num=0;CH>='0'&&CH<='9';num=num*10+CH-'0',CH=getchar());
F && (num=-num);
}
const int N=3e5+10;
int y
,n;
map<int,int>mp;
priority_queue<int>q;
int main(){
std::ios::sync_with_stdio(false);
std::cin.tie(0);
read(n);
for(int i=1; i<=n; i++){
read(y[i]);
q.push(y[i]);
mp[y[i]]++;
}
while(!q.empty()){
int tmp=q.top();
int t=tmp;
while(mp[t] && t!=0){
t>>=1;
}
if(t==0)break;
mp[tmp]--;
mp[t]++;
q.pop();
q.push(t);
}
while(!q.empty()){
printf("%d ", q.top());
q.pop();
}
puts("");
return 0;
}
代码二:
(set来维护,用到了set的排序功能)
//G++ 296ms 2800k
#include <bits/stdc++.h>
#define pr(x) cout << #x << "= " << x << " " ;
#define pl(x) cout << #x << "= " << x << endl;
#define ll __int64
using namespace std;
template<class T> void read(T&num) {
char CH; bool F=false;
for(CH=getchar();CH<'0'||CH>'9';F= CH=='-',CH=getchar());
for(num=0;CH>='0'&&CH<='9';num=num*10+CH-'0',CH=getchar());
F && (num=-num);
}
const int N=3e5+10;
int y
,n;
set<int>s;
int main(){
std::ios::sync_with_stdio(false);
std::cin.tie(0);
read(n);
for(int i=1; i<=n; i++){
read(y[i]);
s.insert(y[i]);
}
while(1){
auto it=s.end();//it为末尾下标+1
it--;
int p=*it;
while(s.find(p)!=s.end() && p!=0){//find没找到的话会返回s.end()
p>>=1;
}
if(p==0)break;
s.erase(*it);
s.insert(p);
}
for(auto it=s.begin(); it!=s.end(); it++){
printf("%d ",*it);
}
puts("");
return 0;
}
描述:
D. Generating Sets
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
You are given a set Y of n distinct positive
integers y1, y2, ..., yn.
Set X of n distinct positive
integers x1, x2, ..., xn is
said to generate set Y if one can transform X to Y by
applying some number of the following two operation to integers in X:
Take any integer xi and
multiply it by two, i.e. replace xi with 2·xi.
Take any integer xi,
multiply it by two and add one, i.e. replace xi with 2·xi + 1.
Note that integers in X are not required to be distinct after each operation.
Two sets of distinct integers X and Y are
equal if they are equal as sets. In other words, if we write elements of the sets in the array in the increasing order, these arrays would be equal.
Note, that any set of integers (or its permutation) generates itself.
You are given a set Y and have to find a set X that
generates Y and the maximum element of X is
mininum possible.
Input
The first line of the input contains a single integer n (1 ≤ n ≤ 50 000) —
the number of elements in Y.
The second line contains n integers y1, ..., yn (1 ≤ yi ≤ 109),
that are guaranteed to be distinct.
Output
Print n integers — set of distinct integers that generate Y and
the maximum element of which is minimum possible. If there are several such sets, print any of them.
Examples
input
5 1 2 3 4 5
output
4 5 2 3 1
input
6 15 14 3 13 1 12
output
12 13 14 7 3 1
input
6 9 7 13 17 5 11
output
4 5 2 6 3 1
题意:
X集合的数 可以有两种方式变换Y 现在给你一个集合Y 求X 且这个X的里最大的数 尽可能小
注意原数列和目标数列都必须满足set内元素的性质(即每个元素都不相同),但是在变化的过程中不需要满足这个条件。
思路:
贪心,每次取出最大的数字,除以2,如果没有重复元素的话就结束(也就是说不必一次就把它除到最小)并且放回集合里面,一直这样操作直到最大的数字无法变化为止。这样的贪心思路才是正确的。
代码一:
(堆来维护)
//G++ 327ms 21300k
#include <bits/stdc++.h>
#define pr(x) cout << #x << "= " << x << " " ;
#define pl(x) cout << #x << "= " << x << endl;
#define ll __int64
using namespace std;
template<class T> void read(T&num) {
char CH; bool F=false;
for(CH=getchar();CH<'0'||CH>'9';F= CH=='-',CH=getchar());
for(num=0;CH>='0'&&CH<='9';num=num*10+CH-'0',CH=getchar());
F && (num=-num);
}
const int N=3e5+10;
int y
,n;
map<int,int>mp;
priority_queue<int>q;
int main(){
std::ios::sync_with_stdio(false);
std::cin.tie(0);
read(n);
for(int i=1; i<=n; i++){
read(y[i]);
q.push(y[i]);
mp[y[i]]++;
}
while(!q.empty()){
int tmp=q.top();
int t=tmp;
while(mp[t] && t!=0){
t>>=1;
}
if(t==0)break;
mp[tmp]--;
mp[t]++;
q.pop();
q.push(t);
}
while(!q.empty()){
printf("%d ", q.top());
q.pop();
}
puts("");
return 0;
}
代码二:
(set来维护,用到了set的排序功能)
//G++ 296ms 2800k
#include <bits/stdc++.h>
#define pr(x) cout << #x << "= " << x << " " ;
#define pl(x) cout << #x << "= " << x << endl;
#define ll __int64
using namespace std;
template<class T> void read(T&num) {
char CH; bool F=false;
for(CH=getchar();CH<'0'||CH>'9';F= CH=='-',CH=getchar());
for(num=0;CH>='0'&&CH<='9';num=num*10+CH-'0',CH=getchar());
F && (num=-num);
}
const int N=3e5+10;
int y
,n;
set<int>s;
int main(){
std::ios::sync_with_stdio(false);
std::cin.tie(0);
read(n);
for(int i=1; i<=n; i++){
read(y[i]);
s.insert(y[i]);
}
while(1){
auto it=s.end();//it为末尾下标+1
it--;
int p=*it;
while(s.find(p)!=s.end() && p!=0){//find没找到的话会返回s.end()
p>>=1;
}
if(p==0)break;
s.erase(*it);
s.insert(p);
}
for(auto it=s.begin(); it!=s.end(); it++){
printf("%d ",*it);
}
puts("");
return 0;
}
相关文章推荐
- 任意一个5位数,比如:34256,把它的各位数字打乱,重新排列,可以得到一个最大的数:65432, 一个最小的数23456。求这两个数字的差,得:41976,把这个数字再次重复上述过程(如果不足5位,
- 编写一个监控Zookeeper的Java程序,可以通过两种方式 :
- 有一个函数int getNum(),每运行一次可以从一个数组V[N]里面取出一个数,N未知,当数取完的时候,函数返回NULL。现在要求写一个函数int get(),这个函数运行一次可以从V[N]里随机
- 给定一个由整数组成二维矩阵(r*c),现在需要找出它的一个子矩阵,使得这个子矩阵内的所有元素之和最大,并把这个子矩阵称为最大子矩阵。
- 现在很多的手机应用,都可能会直接嵌入一个web页面。这样做的好处:一个是功能更新方便,维护起来容易,只需要维护服务器的页面即可,不需要更新客户端;另一个是功能通用,不仅Android可以用,iOS也可
- 例题:把一个超市购物的题做成函数。这个题做成函数没有必要,但可以了解输入参数,输出参数,返回值,函数体,还有结构体,ArryList集合,for循环算结果,以及集合里 .count的使用
- 一个袋子里面有n个球,每个球上面都有一个号码(拥有相同号码的球是无区别的)。如果一个袋子是幸运的当且仅当所有球的号码的和大于所有球的号码的积。 例如:如果袋子里面的球的号码是{1, 1, 2, 3},这个袋子就是幸运的,因为1 + 1 + 2 + 3 > 1 * 1 * 2 * 3 你可以适当从袋子里移除一些球(可以移除0个,但是别移除完),要使移除后的袋子是幸运的。现在让你编程计算一下你可以获得
- 页面中iframe中嵌入一个跨域的页面,让这个页面按照嵌入的页面宽高大小显示的方式;iframe嵌套的页面不可以编辑的问题解决方案
- [转]给你一个单词a,如果通过交换单词中字母的顺序可以得到另外的单词b,那么定义b是a的兄弟单词。现在给你一个字典,用户输入一个单词,让你根据字典找出这个单词有多少个兄弟单词
- 面试题:一个方法和类名相同,那这个是构造方法吗?哪些方式可以获取或设置成员变量的值?
- 牛牛和15朋友来玩打土豪分田地的游戏,牛牛决定让你来分田地,地主的田地可以看成是一个矩形,每个位置有一个价值。分割田地的方法是横竖各切三刀,分成26份,作为领导干部,牛牛总是会选择其中总价值最小的一份田地,作为牛牛最好的朋友,你希望牛牛取得的田地价值和尽可能大,你知道这个值最大可以是多少吗? 输入两个整数n和m(1≤n,m≤75)表示田地的大小,接下来n行,每行包括m个0-9之间的数字,表示每块
- 你就是一个画家!你现在想绘制一幅画,但是你现在没有足够颜色的颜料。为了让问题简单,我们用正整数表示不同颜色的颜料。你知道这幅画需要的n种颜色的颜料,你现在可以去商店购买一些颜料,但是商店不能保证能供应所有颜色的颜料,所以你需要自己混合一些颜料。混合两种不一样的颜色A和颜色B颜料可以产生(A XOR B)这种颜色的颜料(新产生的颜料也可以用作继续混合产生新的颜色,XOR表示异或操作)。本着勤俭节约的
- 阿里巴巴面试算法题:有一个函数int getNum(),每运行一次可以从一个数组V[N]里面取出一个数,N未知,当数取完的时候,函数返回NULL。现在要求写一个函数int get(),这个函数运行一次可以从V[N]里随机取出一个数,而这个数必须是符合1/N
- 给定一个递增序列,a1 <a2 <...<an 。定义这个序列的最大间隔为d=max{ai+1 - ai }(1≤i<n),现在要从a2 ,a3 ..an-1 中删除一个元素。问剩余序列的最大间隔最小是多少?
- 页面中iframe中嵌入一个跨域的页面,让这个页面按照嵌入的页面宽高大小显示的方式;iframe嵌套的页面不可以编辑的问题解决方案
- 有一个Map集合里面存储的是学生的姓名和年龄,内容如下{赵四=21,王二=17,张三=18,小丫=25,李四=26,王五=38}(15分) * a.将里面的元素用两种遍历方式打印到控制台上 *
- 段很长的道路,一个油漆工刷路面,他有两种工具,工具1每次可以刷1米,工具2每次可以刷3米,1)问当道路长度是n米时,使用工具1和工具2配合使用刷完全部道路,共有多少种方式?
- 给你一个单词a,如果通过交换单词中字母的顺序可以得到另外的单词b,那么定义b是a的兄弟单词。现在给你一个字典,用户输入一个单词,让你根据字典找出这个单词有多少个兄弟单词。
- 动态DNS——本质上是IP变化,将任意变换的IP地址绑定给一个固定的二级域名。不管这个线路的IP地址怎样变化,因特网用户还是可以使用这个固定的域名 这样看的话,p2p可以用哇
- android两种方式中自己画一个圆,实现单点触控时拖动图片,跟着拖动点走,并且可以放大或缩小