[ABC254Ex] Multiply or Divide by 2

题目传送门

纪念我人生中的第一发紫题!

本题中有两个操作,分别是① a i ← ⌊ a i 2 ⌋ a_i \leftarrow \lfloor \frac{a_i}{2} \rfloor ai2ai 和 ② a i ← a i × 2 a_i \leftarrow a_i\times2 aiai×2 ,求最少需要多少次才能使 A A A 集合和 B B B 集合中的元素相等

首先我们钦定 a = m a x A , b = m a x B a=max_A,b=max_B a=maxA,b=maxB (因为让我们求最小操作次数,所以我们贪心地想从最大值切入问题,为什么不从最小值的原因后边有)则有三种情况:

  • a = b a=b a=b 此时不用消耗操作次数,直接消掉即可
  • a > b a>b a>b 我们直接反手一个操作①
  • a < b a<b a<b 这个时候此题最精髓的性质出现了:操作②是不是等价于将偶数的 b / 2 b/2 b/2,然后还能愉快的得出如果 b b b 是奇数的时候是无解的(这就是我们要从最大值开始贪心了)

一个下位紫,代码极短

#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define ll long long
using namespace std;
int n,x,y,ans;
priority_queue<int> a,b;
int main() {
   scanf("%d",&n);
   for(int i=1;i<=n;++i) scanf("%d",&x),a.push(x);
   for(int i=1;i<=n;++i) scanf("%d",&x),b.push(x);
   while(!a.empty()){
       x=a.top(),y=b.top();
       a.pop(),b.pop();
       if(x==y) continue;
       ans++;
       if(x>y){
           a.push(x/2),b.push(y);
       }if(x<y){
           if(y&1) return puts("-1"),0;
           else a.push(x),b.push(y/2);
       }
   }
   printf("%d\n",ans);
   return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值