bnuoj24252 Divide
Alice and Bob has found a island of treasure in byteland! They find N kinds of treasures on the island, and each kind of treasure has a certain number, and as in byteland, the value of each treasure will be a power
of 2, such as 1,2,4,8 ...
Now the only problem is how to divide treasures fairly, they need to divide the treasures into two parts, and the value of each part is the sum of all treasures' in this part, they want to make the difference between the value of two parts as small as possible,
can you help them?
Input
First line of the input is a single integer T(1 <= T <= 20), indicating there are T test cases.
For each test case, the first line contain one integer N(2 <= N <= 10^5), indicate the different kinds of treasures.
Then N line followed, each line will have follow two integer ai(0 <= ai <= 10^5) and xi(0 <= xi <= 10^9), indicate there are xi i-th treasures, and the value of each one is 2^ai.
Output
For each case, you should output a single line, first output "Case #t: ", where t indicating the case number between 1 and T, then a string with only '0' and '1' followed, indicate the minimum difference in binary
representation, find more details in samples.
Sample Input
3
2
0 2
2 1
4
0 1
1 1
2 1
3 1
4
0 2
1 1
2 1
3 1
Sample Output
Case #1: 10
Case #2: 1
Case #3: 0
这题是道二进制想法题,给你n种2^a[i]次,num[i]件的物品,问你怎样分配为两堆物品能使两堆的差值最小。这里我们可以把读入的每件物品都用二进制储存起来,用num[i]表示二进制第i位上的数,用jinwei[i]表示这一位是否由前一位进位得到。
然后从高位到低位循环,直到没有进位的且为1的那位退出,那么最小的差值即为当前的位数所表示的数减去其低位加起来的总数。为什么这样是对的呢,因为如果是0或者2,那么一定可以平分,如果是1,且是由进位得到的,那么这个进位可以表示为2个较低位的数。而且2^i>2^(i-1)+2^(i-2)+2^(i-3)+...+2^0,所以这样差值一定是最小的。
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<string>
#include<algorithm>
using namespace std;
#define ll long long
#define inf 0x7fffffff
#define maxn 106000
struct node{
ll num,v;
}a[maxn],b[maxn];
ll jinwei[maxn],num[maxn],ans[maxn];
int main()
{
ll n,m,i,j,T,tot,cnt,cas=0;
scanf("%lld",&T);
while(T--)
{
memset(num,0,sizeof(num));
memset(jinwei,0,sizeof(jinwei));
memset(ans,0,sizeof(ans));
scanf("%lld",&n);
for(i=1;i<=n;i++){
scanf("%lld%lld",&a[i].v,&a[i].num);
num[a[i].v+1]+=a[i].num;
}
tot=0;
for(i=1;i<=105000;i++){
if(num[i]==0)continue;
if(num[i]==1){
tot=i;continue;
}
tot=i;
if(num[i]%2==0){
num[i+1]+=num[i]/2;jinwei[i+1]=1;
num[i]=0;
}
else{
num[i+1]+=num[i]/2;jinwei[i+1]=1;
num[i]=1;
}
}
j=10000000000;
for(i=tot;i>=1;i--){
if(num[i]==0)continue;
if(num[i]==1){
if(jinwei[i]==1)continue;
else{
j=i;break;
}
}
}
if(j==10000000000){
cas++;
printf("Case #%lld: 0\n",cas);continue;
}
if(j==1){
cas++;
printf("Case #%lld: 1\n",cas);continue;
}
for(i=j-1;i>=1;i--){
ans[i]=1-num[i];
}
ans[1]++;
tot=0;
for(i=1;i<=105000;i++){
if(ans[i]==0)continue;
if(ans[i]==1){
tot=i;continue;
}
tot=i;
if(ans[i]%2==0){
ans[i+1]+=ans[i]/2;
ans[i]=0;
}
else{
ans[i+1]+=ans[i]/2;
ans[i]=1;
}
}
cas++;
printf("Case #%lld: ",cas);
for(i=tot;i>=1;i--){
printf("%lld",ans[i]);
}
printf("\n");
}
return 0;
}
bnuoj24252 Divide的更多相关文章
- [LeetCode] Divide Two Integers 两数相除
Divide two integers without using multiplication, division and mod operator. If it is overflow, retu ...
- Pairwise Sum and Divide 51nod
1305 Pairwise Sum and Divide 题目来源: HackerRank 基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题 收藏 关注 有这样 ...
- Conquer and Divide经典例子之Strassen算法解决大型矩阵的相乘
在通过汉诺塔问题理解递归的精髓中我讲解了怎么把一个复杂的问题一步步recursively划分了成简单显而易见的小问题.其实这个解决问题的思路就是算法中常用的divide and conquer, 这篇 ...
- UVA - 10375 Choose and divide[唯一分解定理]
UVA - 10375 Choose and divide Choose and divide Time Limit: 1000MS Memory Limit: 65536K Total Subm ...
- [leetcode] 29. divide two integers
这道题目一直不会做,因为要考虑的corner case 太多. 1. divisor equals 0. 2. dividend equals 0. 3. Is the result negative ...
- Leetcode Divide Two Integers
Divide two integers without using multiplication, division and mod operator. 不用乘.除.求余操作,返回两整数相除的结果,结 ...
- uva10375 Choose and Divide(唯一分解定理)
uva10375 Choose and Divide(唯一分解定理) 题意: 已知C(m,n)=m! / (n!*(m-n!)),输入整数p,q,r,s(p>=q,r>=s,p,q,r,s ...
- 51nod1305 Pairwise Sum and Divide
题目链接:51nod 1305 Pairwise Sum and Divide 看完题我想都没想就直接暴力做了,AC后突然就反应过来了... Floor( (a+b)/(a*b) )=Floor( ( ...
- leetcode-【中等题】Divide Two Integers
题目 Divide two integers without using multiplication, division and mod operator. If it is overflow, r ...
随机推荐
- nginx日志按天切割
要求:以天为单位进行日志文件的切割,如host.access_20150915.log, 日志保留最近10天的, 超过10天的日志文件则进行删除. nginxcutlogs.sh脚本内容: #!/bi ...
- canvas多重阴影发光效果
canvas多重阴影发光效果 前言 在一个项目中,客户提了一个发光的效果,效果图如下: 阴影 有的人可能会说,这个用阴影其实就可以实现.但是从图中可以看出,是一个比较强烈的发光效果.实际的应用过程中我 ...
- 【Oracle】修改列的大小
alter table 表名 modify column_name varchar2(32) alter table 表名 modify (column_name1 varchar(20) defa ...
- Kafka 探险 - 生产者源码分析: 核心组件
这个 Kafka 的专题,我会从系统整体架构,设计到代码落地.和大家一起杠源码,学技巧,涨知识.希望大家持续关注一起见证成长! 我相信:技术的道路,十年如一日!十年磨一剑! 往期文章 Kafka 探险 ...
- kafka(三)原理剖析
一.生产者消息分区机制原理剖析 在使用Kafka 生产和消费消息的时候,肯定是希望能够将数据均匀地分配到所有服务器上.比如很多公司使用 Kafka 收集应用服务器的日志数据,这种数据都是很多的,特别是 ...
- Eureka详解系列(一)--先谈谈负载均衡器
这个系列开始研究 Eureka,在此之前,先来谈谈负载均衡器. 本质上,Eureka 就是一个负载均衡器,可能有的人会说,它是一个服务注册中心,用来注册服务的,这种说法不能说错,只是有点片面. 在这篇 ...
- Java自学笔记之学生管理系统
实现:学生管理系统,实现学生信息的添加.修改.查询和删除功能 涉及:集合的基础知识(集合遍历,值得获取与替换,set/get方法) 代码如下: Student文件 1 package Demo_120 ...
- Java 迭代器的使用 Iterator
Java的集合类可以使用for ... each循环 List Set Queue Deque 我们以List为例 其实一个java编译器并不知道如何遍历一个List 编译器只是把一个for ... ...
- 利用JavaUDPSocket+多线程模拟实现一个简单的聊天室程序
对Socket的一点个人理解:Socket原意是指插座.家家户户都有五花八门的家用电器,但它们共用统一制式的插座.这样做的好处就是将所有家用电器的通电方式统一化,不需要大费周章地在墙壁上凿洞并专门接电 ...
- 树莓派安装 Ubuntu 20.04 LTS 碰壁指南
树莓派安装 Ubuntu 20.04 LTS 碰壁指南 设备 Raspberry 4B 4+32G 系统 Ubuntu 20.04 LTS 1.镜像下载与烧录 镜像下载地址:https://cdima ...