2015弱校聯萌十一大決戰之背水一戰 D. Divide 二進位制思維題
http://www.bnuoj.com/v3/contest_show.php?cid=6869#problem/D
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
/**
2015弱校聯萌十一大決戰之背水一戰 D. Divide 二進位制思維題
題目大意:給定寫物品每個有2^a[i]重,每種x[i]個,問將二者平均分成兩份,二者的最小差的二進位制表示
解題思路:資料如果小點,就是一個揹包的問題了。首先從低位往高位處理,jin[i]表示第i位有沒有前一位的進位,num[i]表示
進位後i位置的數,我們找到最前一個該位為1,且並無前一位進位的j,那麼2^j,為一份,其前面的所有為一份,做差
就可以了。因為如果該位為1但有進位的話,完全可以看出改位為0,前一位為2,則可以分成兩份的。
*/
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
const int maxn=100010;
int n,a[maxn],jin[maxn];
LL num[maxn],x[maxn];
int main()
{
int T,tt=0;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
int maxx=-1;
memset(num,0,sizeof(num));
for(int i=0;i<n;i++)scanf("%d%lld",&a[i],&x[i]),maxx=max(maxx,a[i]),num[a[i]]+=x[i];
// printf(">>>before");
// for(int i=0;i<=maxx;i++)printf("%lld",num[i]);
// printf("\n");
memset(jin,0,sizeof(jin));
for(int i=0;i<=maxx;i++)
{
if(num[i]/2)jin[i+1]=1;
num[i+1]+=num[i]/2;
num[i]%=2;
}
// printf(">>>");
// for(int i=0;i<=maxx;i++)printf("%lld",num[i]);
// printf("\n");
bool flag=0;
for(int i=maxx;i>=0;i--)
{
if(num[i]&&jin[i]==0)
{
maxx=i;
flag=1;
break;
}
}
printf("Case #%d: ",++tt);
if(flag==0)
{
puts("0");
continue;
}
int i;
for(i=0;i<maxx;i++)
{
if(num[i]==1)
{
num[i]=1;
for(int j=i+1;j<maxx;j++)num[j]^=1;
break;
}
}
num[maxx]=(i==maxx);
for(int i=maxx;i>=0;i--)
{
if(num[i]==1)
{
for(int j=i;j>=0;j--)printf("%lld",num[j]);
break;
}
}
printf("\n");
}
return 0;
}
相關文章
- 弱校聯萌十一大決戰之強力熱身 C.Censor (KMP變形 好題)KMP
- 二進位制方式解決 power 問題
- 進位制之間的轉換之“十六進位制 轉 十進位制 轉 二進位制 方案”
- 二進位制,八進位制,十進位制,十六進位制之間的轉換
- 奇偶校驗(轉換二進位制、bitset)
- 大話二進位制,八進位制,十進位制,十六進位制之間的轉換
- D. Divide and EqualizeIDE
- mysql二進位制包安裝與配置實戰記錄MySql
- 二進位制與二進位制運算
- 進位制詳解:二進位制、八進位制和十六進位制
- 一看就懂二進位制、八進位制、十六進位制數轉換十進位制
- JavaScript 二進位制、八進位制與十六進位制JavaScript
- 二進位制陣列實戰 - 純前端匯出Excel檔案陣列前端Excel
- 二進位制陣列實戰 – 純前端匯出Excel檔案陣列前端Excel
- (二進位制)
- 二進位制
- 十進位制——二 (八、十六 )進位制
- 二進位制,八進位制,十進位制,十六進位制的相互轉換
- C++二進位制相容問題及解決方法C++
- 【進位制轉換】二進位制、十六進位制、十進位制、八進位制對應關係
- 二進位制漏洞挖掘之整數溢位
- 二進位制、十進位制與十六進位制相互轉化
- java中二進位制、八進位制、十進位制、十六進位制的轉換Java
- Python 進位制互相轉換(二進位制、十進位制和十六進位制)Python
- 計算機基礎進位制轉換(二進位制、八進位制、十進位制、十六進位制)計算機
- Swift之struct二進位制大小分析SwiftStruct
- 二進位制轉十進位制快速方法
- JAVA 二進位制,八進位制,十六進位制,十進位制間進行相互轉換Java
- 什麼是二進位制?二進位制如何轉換?
- 數字邏輯練習題-(二進位制/16進位制模擬)
- 04 二進位制
- 計算機程式的思維邏輯 (57) - 二進位制檔案和位元組流計算機
- JavaScript十進位制轉換為二進位制JavaScript
- Oracle二進位制與十進位制轉換Oracle
- 十進位制轉二進位制推導(草稿)
- JavaScript 進位制轉換(2進位制、8進位制、10進位制、16進位制之間的轉換)JavaScript
- [計算機基礎] 計算機進位制轉換:二進位制、八進位制、十進位制、十六進位制計算機
- python進位制轉換(二進位制、十進位制和十六進位制)及注意事項Python