Codeforces Round #840 (Div. 2) A — B

Codeforces Round #840 (Div. 2)

A. Absolute Maximization
题目大意

给你一个有n个数的数组,每次操作可以交换两个数相同二进制位上的数,求任意操作次数后数组中最大值与最小值最大差值。

题目分析

因可以任意交换,则我们可以尽可能的让差值而二进制位1更多

遍历所有数组元素的二进制位,某一位上满足1的个数大于0小于n,则可以累加到答案中(等于n是说明每个元素此位都是1,做减法时会被剪掉)

code
#include<bits/stdc++.h>

using namespace std;

const int N = 1010;

int n, m, k, t;
int a[N];

void solve()
{
    cin >> n;
    for(int i = 1; i <= n; i ++) cin >> a[i];

    int ans = 0;
    for(int k = 0; k <= 11; k ++)
    {
        int cnt = 0;
        for(int i = 1; i <= n; i ++)
            if(a[i] >> k & 1) cnt ++;
        if(cnt && cnt  < n) ans += (1 << k);
    }

    cout << ans << "\n";
}

int main()
{
    cin >> t;
    while(t --) solve();
    return 0;
}

B. Incinerate
题目大意

有n个怪物,第i个怪物拥有生命值hi和能量pi。一次攻击可以对所有活着的怪物造成k点伤害。

在每次攻击之后,怪物都会前进。在所有目前活着的怪物中,每次攻击后从k的值中减去拥有最少力量的怪物。

问能否做掉所有怪物

题目分析

数据范围不是很大,可以根据题意进行模拟。

一个个体能量值和生命值是绑定的,所以可以通过pair来整体存,另外每次都要考虑能量值最小的怪兽,所以用优先队列存储可以自动进行排列(注:因其中元素为pair类型,所以默认按优先前值排序)

因每次操作生命值的变化较为繁琐,我们累计伤害与生命值作比较

code
#include<bits/stdc++.h>

using namespace std;

const int N = 1e5 + 10;

typedef pair<int, int> PII;

int h[N], p[N];
int n, m, k, t;

void solve()
{
    priority_queue<PII, vector<PII>, greater<PII>>q;

    cin >> n >> k;
    for(int i = 1; i <= n; i ++) cin >> h[i];
    for(int i = 1; i <= n; i ++) cin >> p[i];
    for(int i = 1; i <= n; i ++) q.push({p[i], h[i]});

    bool flag = false;
    int har = k;
    while(q.size())
    {
        auto rt = q.top();
        q.pop();
        int rp = rt.first, rh = rt.second;

        if(har >= rh) continue;
        else
        {
            q.push({rp, rh});
            k -= rp;
            if(k <= 0)
            {
                puts("NO");
                flag = true;
                break;
            }
            har += k;
        }
    }

    if(!flag)puts("YES");
}

int main()
{
    cin >> t;
    while(t --) solve();
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值