AtCoder Beginner Contest 376
A - Candy Button
#include <bits/stdc++.h>
using namespace std;
using i32 = int32_t;
using i64 = long long;
using vi = vector<int>;
using pii = pair<int,int>;
i32 main(){
ios::sync_with_stdio(false), cin.tie(nullptr);
int n, c;
cin >> n >> c;
int res = 1, lst;
cin >> lst;
for(int i = 2, x; i <= n; i ++) {
cin >> x;
if(x < lst + c) continue;
lst = x, res ++;
}
cout << res;
return 0;
}
B - Hands on Ring (Easy)
这里要注意的就是移动过程中不能出现手跨越手的情况,因此我们要在选择不会跨越的情况。
#include <bits/stdc++.h>
using namespace std;
using i32 = int32_t;
using i64 = long long;
using vi = vector<int>;
using pii = pair<int,int>;
i32 main(){
ios::sync_with_stdio(false), cin.tie(nullptr);
int n, q;
cin >> n >> q;
int l = 1, r = 2;
int res = 0;
while(q --) {
string h;
int t;
cin >> h >> t;
if(h == "L") {
if(l == t) continue;
if(min(t, l) <= r and r <= max(t, l))
res += n - abs(t - l);
else
res += abs(t - l);
l = t;
} else {
if(r == t) continue;
if(min(t, r) <= l and l <= max(t, r))
res += n - abs(t - r);
else
res += abs(t - r);
r = t;
}
}
cout << res;
return 0;
}
C - Prepare Another Box
我们可以二分枚举买的盒子的大小,然后贪心的尝试匹配一下。怎么贪心?我们可以把盒子和物品都排个序即可。其中物品不用每次都排序,但盒子需要。其实盒子中\(N-1\)个盒子的相对位置是固定的。我们可以先把原始盒子排序,然后每次加入一个后再排序,这样的复杂度是不会跑满\(O(N\log N)\)的。
#include <bits/stdc++.h>
using namespace std;
using i32 = int32_t;
using i64 = long long;
using vi = vector<int>;
using pii = pair<int,int>;
const int inf = INT_MAX / 2;
i32 main(){
ios::sync_with_stdio(false), cin.tie(nullptr);
int n;
cin >> n;
vi a(n), b(n - 1);
for(auto &i : a) cin >> i;
for(auto &i : b) cin >> i;
ranges::sort(a);
ranges::sort(b);
auto check = [=](int x) {
auto c = b;
c.push_back(x);
ranges::sort(c);
for(int i = 0; i < n; i ++)
if(a[i] > c[i]) return false;
return true;
};
int l = 0, r = inf, res = -1;
while(l <= r) {
int mid = (l + r) / 2;
if(check(mid)) res = mid, r = mid - 1;
else l = mid + 1;
}
cout << res;
return 0;
}
当然了还有一种思路是,贪心的匹配较大的,找到第一个匹配不上的,此时就必须要购买一个,在验证剩下的是否都可以匹配上。
#include <bits/stdc++.h>
using namespace std;
int main(){
ios::sync_with_stdio(false), cin.tie(nullptr);
int n;
cin >> n;
vector<int> a(n), b(n - 1);
for(auto &i : a) cin >> i;
for(auto &i : b) cin >> i;
ranges::sort(a);
ranges::sort(b);
int x = n - 1, y = n - 2;
int res = 0;
while(x >= 0 and y >= 0) {
if(b[y] >= a[x]) {
x --, y --;
} else {
res = x;
break;
}
}
int f = 1;
x --;
while(x >= 0 and y >= 0){
if(b[y] >= a[x]) {
x --, y --;
} else {
f = 0;
break;
}
}
if(f) {
cout << a[res];
} else {
cout << -1;
}
}
D - Cycle
从 1 开始的 bfs 就好了。
#include <bits/stdc++.h>
using namespace std;
using i32 = int32_t;
using i64 = long long;
using vi = vector<int>;
using pii = pair<int,int>;
const int inf = INT_MAX / 2;
vector<vi> e;
i32 main(){
ios::sync_with_stdio(false), cin.tie(nullptr);
int n, m;
cin >> n >> m;
vector<vi> e(n + 1);
for(int x, y; m ; m --) {
cin >> x >> y;
e[x].push_back(y);
}
vi dep(n + 1, inf);
dep[1] = 1;
queue<int> q;
q.push(1);
while(not q.empty()) {
int x = q.front();
q.pop();
for(auto y : e[x]) {
if(y == 1) {
cout << dep[x];
return 0;
}
if(dep[y] != inf) continue;
dep[y] = dep[x] + 1;
q.push(y);
}
}
cout << -1;
return 0;
}
E - Max × Sum
考虑枚举一下\(\max\),贪心的最小的\(k\)个数即可。
#include <bits/stdc++.h>
using namespace std;
using i32 = int32_t;
using i64 = long long;
#define int i64
using vi = vector<int>;
using pii = pair<int,int>;
const int inf = LLONG_MAX / 2;
void solve(){
int n, k;
cin >> n >> k;
vector<pii> p(n);
for(auto &[a, b] : p) cin >> a;
for(auto &[a, b] : p) cin >> b;
ranges::sort(p);
int sum = 0;
priority_queue<int> heap;
for(int i = 0; i < k - 1; i ++) {
heap.push(p[i].second);
sum += p[i].second;
}
int res = inf;
for(int i = k - 1; i < n; i ++) {
heap.push(p[i].second);
sum += p[i].second;
if(heap.size() > k) {
sum -= heap.top();
heap.pop();
}
res = min(res, sum * p[i].first);
}
cout << res << "\n";
}
i32 main(){
ios::sync_with_stdio(false), cin.tie(nullptr);
int T;
cin >> T;
while(T --)
solve();
return 0;
}