Codeforces Round #679 (Div. 1, based on Technocup 2021 Elimination Round 1)题解
A.Perform Easily
题解:考虑枚举最小值,然后对于每个$b_i$,减去能使减后的值仍大于最小值的最大$a_i$,这么做的时间复杂度为$O(36n^2)$
我们发现枚举最小值后,并不需要遍历每个数,而只需要找到对于$k \in [1,6]$的
$$\max\{b_i-a_k\},minn+a_k\leq b_i<minn+a_{k+1}$$
用set维护即可$O(6 \log n)$找到最大值
总复杂度是$O(36n\log n)$
#include <bits/stdc++.h>
using namespace std;
int n, b[100011], a[7], minn, ans;
set <int> s;
int main() {
for(int i = 1; i <= 6; i++) scanf("%d", &a[i]);
scanf("%d", &n); minn = 2e9;
for(int i = 1; i <= n; i++) {
scanf("%d", &b[i]);
minn = min(minn, b[i]);
s.insert(b[i]);
}
sort(a+1, a+7); ans = 2e9;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= 6; j++) {
if(b[i] - a[j] > minn - a[1]) continue;
int Min = b[i] - a[j], Max = 0;
for(int k = 2; k <= 6; k++) {
set<int>::iterator it = s.lower_bound(Min+a[k]);
if(it == s.begin()) continue;
it--;
Max = max(Max, *it - a[k-1]);
}
set<int>::iterator it = s.end(); it--;
Max = max(Max, *it - a[6]);
ans = min(ans, Max - Min);
}
printf("%d\n", ans);
return 0;
}
B.Shurikens
翻译好评
题解:这题似乎比A还简单
我们倒序进行操作,维护一个栈
对于每个购买操作,我们把它压入栈中
对于每个放置操作,我们只需取出栈顶
如果当前压入栈中的数大于栈顶元素/弹栈时栈为空,则无解
考虑正确性:
栈中存储的是接下来要购买的物品价格(也即之前放置的物品),由于购买时一定买最便宜的,所以最便宜的最后加入一定是最优的
如果当前压入栈中的数大于栈顶元素,那么当前元素和栈顶元素都会在前面放入,不符合买最便宜的要求,无解
时间复杂度$O(n)$
#include <bits/stdc++.h>
using namespace std;
int n, sta[200011], cnt;
int s[200011], ans[200011];
char opt[200011];
int main() {
scanf("%d", &n); n *= 2;
for(int i = 1; i <= n; i++) {
cin >> opt[i];
if(opt[i] == '-') scanf("%d", &s[i]);
}
for(int i = n; i >= 1; i--) {
if(opt[i] == '-') {
if(cnt && s[i] > sta[cnt]) {
cout << "NO" << endl;
return 0;
}
sta[++cnt] = s[i];
}
else {
if(!cnt) {
cout << "NO" << endl;
return 0;
}
ans[i] = sta[cnt--];
}
}
cout << "YES" << endl;
for(int i = 1; i <= n; i++)
if(opt[i] == '+') cout << ans[i] << " ";
return 0;
}
C.Solo mid Oracle
我的数学真的太差了啊啊啊
推式子推错了,还不会算最大决策点,人没了
于是看了题解
题解:首先如果$a>b*c$,则答案为$-1$
我们先瞎jb推出来第$i$次施法的瞬间造成的总伤害,然后要找一个最大决策点
根据题解,这个最大贡献点是$\lfloor \dfrac{a-1}{b*d}+1 \rfloor$,于是就做完了
我原来还想三分做,发现会爆$\text{long long}$,其实应该可以写个高精过掉的,但是我懒得写了
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int t;
ll a, b, c, d, ans, sum;
ll calc(ll i) {
sum = 0;
ll tim = (i-1) * d + 1;
sum = a * i;
sum -= b * c * i;
sum += b * i * (1 + c - tim) + b * d * (i - 1) * i / 2;
return sum;
}
void solve() {
scanf("%lld%lld%lld%lld", &a, &b, &c, &d);
if(b * c < a) {
printf("-1\n");
return;
}
ll answ = (a-1) / (b*d) + 1;
printf("%lld\n", calc(answ));
}
int main() {
scanf("%d", &t);
while(t--) solve();
return 0;
}
所以这道题是对B题太水的弥补???

浙公网安备 33010602011771号