Codeforces Global Round 30 (Div. 1 + Div. 2)
A
给定长度为\(n\)的序列\(a\),现在可以执行操作:
- 选择\(a_i\)和\(a_{i+1}\),并用\(a_i\leq y\leq a_{i+1}\)的\(y\)替换\(a_i\)和\(a_{i+1}\)
可以知道在进行\(n-1\)操作后,序列\(a\)只剩一个元素,问最后剩余元素是否可以恰好等于\(x\)。
sol:
其实我们只需要对\(a\)排序,然后看是否\(a_1\leq x\leq a_n\),如果是,那么就是可以的,否则就不行。
B
给定严格单调增的正整数序列\(a\),满足\(1\leq a_1<a_2<\dots<a_n\),现在需要找到两个不同元素\(x,y\),使得\(x<y\)且\(y\mod x\)是偶数,如果不存在,输出-1。
sol:
这其实是一道性质题,所以可以直接暴力做。
可以分类讨论一下,如果存在两个及以上的偶数,那么我们直接输出任意两个偶数即可。
如果只有一个偶数,我们先拿其他所有奇数元素进行尝试,看是否能满足。
如果还是不满足或者没有偶数,那么现在我们只看奇数是否可以满足要求,假设有奇数序列\(b_1,b_2,\dots,b_k\),如果\(b_{i+1}<2\times b_i\),那么\(b_{i+1}\mod b_i=b_{i+1}-b_i\),那么肯定是偶数。
也就是说如果要构造每次\(b_{i+1}\geq b_i\times 2\),那么\(k\leq \log{V}=32\),所以总是可以在\(n\log {V}\)找到答案或者确定无解。
C
现在有\(n\)把🗡,\(m\)个怪物,每把🗡的伤害为\(a_i\),每只怪物的血量为\(b_i\),当且仅当\(x\geq y\)时,伤害为\(x\)的🗡可以杀死生命值为\(y\)的怪物。同时每只怪物还对应一个属性\(c_i\),如果杀死第\(i\)只怪物,同时\(c_i>0\),那么可以获得一把伤害为\(\max(a_i,c_i)\);否则仅能杀死这只怪物。
现在想知道最多可以杀死多少只怪物,每只怪物只能杀一次。
sol:
这其实是一个很经典的贪心。
因为在杀死怪物后,我们可以获得🗡,因此我们开一个小顶堆来存每把🗡。我们从小枚举🗡,将现在可以杀死的怪物都加进一个容器中,同时即然都可以杀死,我们不关心他们的血量,只关心杀死怪物带来的新🗡,所以我们将怪物的属性\(c_i\)加进前面的容器中,因为我们肯定是希望能够获得伤害更大的🗡,所以我们用一个大顶堆来保存杀死怪物的属性。
这样就可以直接做了:
void solve() {
int n,m;
cin >> n >> m;
vector<int> a(n+1),b(m+1),c(m+1);
vector<pii> d(m+1);
for(int i=1;i<=n;i++) cin >> a[i];
for(int i=1;i<=m;i++) cin >> b[i];
for(int i=1;i<=m;i++) cin >> c[i];
for(int i=1;i<=m;i++) d[i]={b[i],c[i]};
sort(d.begin()+1,d.end());
priority_queue<int,vector<int>,greater<int>> mn;
for(int i=1;i<=n;i++) mn.push(a[i]);
priority_queue<int> mx;
// vector<int> vis(n+1);
int i=1;
int ans=0;
while(1){
int x=mn.top();
mn.pop();
while(i<=m&&d[i].first<=x){
mx.push(d[i].second);
i++;
}
//统计答案
if(!mx.empty()){
ans++;
if(mx.top()>0){
mn.push(max(x,mx.top()));
}
mx.pop();
}
if(mn.empty()) break;
}
cout << ans << endl;
}
D
阴间得很,当时主播脑壳已经痛了,写不来,只写了模拟,但是wa2了。

浙公网安备 33010602011771号