Problem B. Memory Banks

11 篇文章 0 订阅

Description

We have purchased 60 different types of memory banks, typed as 0 to 59, A bank of type i has 2^i memory capacity. We have Xi

memory banks of type i.
We also have n workstations numbered from 1 to n. The ith workstation needs exactly (no more and no less) Wi

memory capacity to work.
Each workstation can use unlimited amount of memory banks, Total memory capacity of this workstation is the sum of capacity of all memory banks it used.
We need to make all workstations work and calculate the total capacity of unused memory banks, can you help us?

 

Input

Input is given from Standard Input in the following format:
X0

... X59
n
W1 ... Wn
Constraints
0 ≤ Xi ≤ 2^60
1 ≤ n ≤ 100000
0 ≤ Wi

≤ 2^60
All of them are integers.

 

Output

Print one line denotes the answer.
If it is possible to make all workstations work, output a single number represents the total capacity of unused memory banks. It maybe very large, you should modulo 1000000007(10^9 + 7)
Otherwise output -1

 

Sample Input

 

4 2 2 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 10 8 16 2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 2 4 8 1

 

Sample Output

 

6 -1


题意:你有面值为2^i的硬币a[i]枚,问凑完所有b[i]元钱后还剩多少钱

思路:就像买东西找零,先给大的面值,然后找小的,如果凑不出就输出-1

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
#define ll long long
#define maxn 205000
#define mod 1000000007
ll a[100],b[110000],p[100];
inline ll read(){
    ll w=0,x = 0;char c = 0;
    while(!isdigit(c))w|=c=='-',c=getchar();
    while(isdigit(c))x=(x<<1)+(x<<3)+(c^48),c=getchar();
    return w?-x:x;
}
int main()
{
    p[0] = 1;
    for(int i = 1; i <= 59; i++) p[i]=p[i-1]*2;
    while(scanf("%lld",&a[0])!=EOF)
    {
        ll ans=0;
        for(int i=1;i<=59;i++)
        {
            a[i] = read();
        }
        int n,flag = 0;
        scanf("%d",&n);
        for(int i = 1; i <= n; i++)
            b[i] = read();
        for(int i = 1; i <= n; i++){
            for(int j = 59; j>-1; j--){
                if(a[j]){
                    ll cnt = b[i]/p[j];
                    ll l = min(cnt,a[j]);
                    b[i]-=l*p[j];
                    a[j]-=l;
                }
            }
            if(b[i]>0){
                flag = 1;
                break;
            }
        }
        if(flag) printf("-1\n");
        else {

            for(int i = 0; i <= 59; i++){
                ans+=(a[i]%mod)*(p[i]%mod);
                ans%=mod;
            }
            printf("%lld\n",ans);
        }

    }
}
/*
10000
17195
20500
36608
14502
28932
16584
33156
52
104
1564
3099
25647
51289
*/

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值