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;
}