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的更多相关文章

  1. [LeetCode] Divide Two Integers 两数相除

    Divide two integers without using multiplication, division and mod operator. If it is overflow, retu ...

  2. Pairwise Sum and Divide 51nod

      1305 Pairwise Sum and Divide 题目来源: HackerRank 基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题  收藏  关注 有这样 ...

  3. Conquer and Divide经典例子之Strassen算法解决大型矩阵的相乘

    在通过汉诺塔问题理解递归的精髓中我讲解了怎么把一个复杂的问题一步步recursively划分了成简单显而易见的小问题.其实这个解决问题的思路就是算法中常用的divide and conquer, 这篇 ...

  4. UVA - 10375 Choose and divide[唯一分解定理]

    UVA - 10375 Choose and divide Choose and divide Time Limit: 1000MS   Memory Limit: 65536K Total Subm ...

  5. [leetcode] 29. divide two integers

    这道题目一直不会做,因为要考虑的corner case 太多. 1. divisor equals 0. 2. dividend equals 0. 3. Is the result negative ...

  6. Leetcode Divide Two Integers

    Divide two integers without using multiplication, division and mod operator. 不用乘.除.求余操作,返回两整数相除的结果,结 ...

  7. 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 ...

  8. 51nod1305 Pairwise Sum and Divide

    题目链接:51nod 1305 Pairwise Sum and Divide 看完题我想都没想就直接暴力做了,AC后突然就反应过来了... Floor( (a+b)/(a*b) )=Floor( ( ...

  9. leetcode-【中等题】Divide Two Integers

    题目 Divide two integers without using multiplication, division and mod operator. If it is overflow, r ...

随机推荐

  1. LeetCode 371两数之和

    题目描述: 不使用运算符 + 和 - ​​​​​​​,计算两整数 ​​​​​​​a .b ​​​​​​​之和. 思路: 既然不能使用运算符操作就要考虑到,位运算的加法. 加法有进位的时候和不进位的时候 ...

  2. C++ 异常机制(上)

    目录 一.概念 二.异常的好处 三.基本语法 四.栈解旋 五.异常接口声明 六.异常对象的内存模型 七.异常对象的生命周期 一.概念 异常:存在于运行时的反常行为,这些行为超过了函数的正常的功能范围. ...

  3. 【Docker】在Linux系统中安装Docker虚拟机、启动停止重启查看Docker命令

    安装Docker 文章目录 安装Docker Docker虚拟机架构 在Linux系统中安装Docker虚拟机 管理Docker虚拟机 参考资料 Docker虚拟机架构 Docker创建的所有虚拟实例 ...

  4. 【Linux】Linux基础命令 - 目录相关的命令 ls 、cd、du

    文章目录 目录相关的命令 ls 命令:列出文件和目录 cd 命令:切换目录 du 命令:显示目录包含的文件大小 总结 参考资料 巩固和复习Linux系统基础命令知识 目录相关的命令 ls 命令:列出文 ...

  5. uni-app开发经验分享六:页面跳转及提示框

    在我们开发的uni-app的过程中,页面跳转及提示框往往是我们做数据交互及结果反馈所要使用的功能,这里分享下我收集的一些方法及看法. 一:页面跳转 事件跳转 :指通过tap等事件来实现页面的跳转,跳转 ...

  6. 导出exe的经验

    安装pyinstaller 首先要找到scripts的绝对路径(主要是找到scripts就行了 先是安装C:\Users\96290\AppData\Local\Programs\Python\Pyt ...

  7. Py-时间,随机,os,sys,jsonpickle序列化,shelve,xml模块

    内置模块 1.时间模块 第一:time.time()是时间戳 时间戳默认是 从1970年到现在过的秒数,是一个很长的数值它可以做时间的计算以及显示 第二:localtime() 获取当前的时间,按元组 ...

  8. 如果using语句中出现异常,资源会被释放掉吗?

    <CLR Via C#>第三版 P489 在using内部抛出了异常,被using的对象还是会被释放掉. Using编译时会自动生成Try Finally代码块. 同样Using只能用于实 ...

  9. 转 3 jmeter的两种录制方法

      录制1-badboy(推荐) badboy是一款自动化测试工具,它可以完成简单的功能测试和性能测试.其实它是一款独立的测试工具,只不过它录制东西导出的格式适用于jmeter,所以我们经常把jmet ...

  10. 华为路由配置IPSec

    用该方法配置后用抓包工具抓取的就看不到两个通讯点的IP,而显示的是加密点的IP. 原文:https://www.cnblogs.com/yangyang1988/p/11559819.html