Codeforces Round #840 (Div. 2) and Enigma 2022 - Cybros LNMIIT A--B

时间:2023-01-01 21:59:47

​https://codeforces.com/contest/1763​


A. Absolute Maximization二进制操作

经典的利用二进制位数操作的题,| 和 &。

最大值肯定是所有元素的或。

最小值是所有元素的与。

为什么?或就类似加法,每个位数有1的全都归并到一个数上,因此这个数是包含所有元素的每个位的1的,它必然是最大的。

与,则类似减法,把所有元素每一位的1都尝试减去,最终留下的是所有元素共同是1的位,也就是最小的。

#include <bits/stdc++.h>
#define endl '\n'
using namespace std;

void s(){
int n;
cin >> n;
vector<int> a(n);
for(auto &i : a) cin >> i;

int maxone = 0, minone = -1;
for(int i = 0; i < n; i ++){
maxone = maxone | a[i];
minone = minone & a[i];
}
cout << maxone - minone << endl;
}

int main(){
cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);
int t;
cin >> t;
while(t--) s();


return 0;
}



B. Incinerate模拟

暴力模拟每一次attack就行,不会超时。

注意,有些元素是最小值,但是血很厚,需要反复杀很多次。有些元素动态的血量清零后,就不能再考虑它了。

实现思路:用一个all来存当前的累积伤害,如果这个怪物的血量低于累积伤害,说明它被kill了,将它弹掉或者忽略掉就行。

#include <bits/stdc++.h>
#define endl '\n'
using namespace std;

struct node{
int index;
long long hp, power;
};

long long n, k;

bool operator <(const struct node &a, const struct node &b){
return a.power > b.power; //小根堆
}

void s(){

cin >> n >> k;
vector<long long> h(n + 10), p(n + 10);// 别放全局变量
priority_queue<struct node> heap;

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


long long nowk = k, all = k;
while(!heap.empty() && nowk > 0){ //可能没kill,需要反复杀掉
while(!heap.empty() && heap.top().hp <= all) heap.pop();
while(!heap.empty() && heap.top().hp > all && nowk > 0){
nowk -= heap.top().power;
all += nowk;
}
}
while(!heap.empty() && heap.top().hp <= all) heap.pop();


if(!heap.empty()) {
cout << "NO\n";
}else cout << "YES\n";

}

int main(){
cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);
int t;
cin >> t;
while(t--) s();


return 0;
}