VP Educational Codeforces Round 68 (Rated for Div. 2)
A. Remove a Progression
题意:\([1, n]\)排成一行,每次删掉第\(i\)个数,求最后第\(x\)个数是谁。
模拟发现偶数都会留下。所以答案就是\(x\times 2\)。
点击查看代码
void solve() {
int n, x;
std::cin >> n >> x;
std::cout << x * 2 << "\n";
}
B. Yet Another Crosses Problem
题意:一个矩阵,判断需要填多少数才能满足一个\((x, y)\)使得第\(x\)行\(y\)列都被填满。
记录每行填了多少和每列填了多少,然后对于每个\((x, y)\)讨论即可。
点击查看代码
void solve() {
int n, m;
std::cin >> n >> m;
std::vector<std::string> s(n);
for (int i = 0; i < n; ++ i) {
std::cin >> s[i];
}
std::vector<int> row(n), col(m);
for (int i = 0; i < n; ++ i) {
for (int j = 0; j < m; ++ j) {
if (s[i][j] == '*') {
row[i] ++ ;
col[j] ++ ;
}
}
}
int ans = n + m;
for (int i = 0; i < n; ++ i) {
for (int j = 0; j < m; ++ j) {
ans = std::min(ans, n + m - 1 - (row[i] + col[j]) + (s[i][j] == '*'));
}
}
std::cout << ans << "\n";
}
C. From S To T
题意:三个字符串,\(s, t, p\),需要把\(s\)变成\(t\),可以把\(p\)中任意字符插到\(s\)任意位置。
从前往后匹配,\(s\)能匹配就匹配,不能就从\(p\)拿。如果最后\(s\)有多余的也不行。
点击查看代码
void solve() {
std::string s, t, p;
std::cin >> s >> t >> p;
int n = s.size(), m = t.size();
std::array<int, 26> cnt{};
for (auto & c : p) {
++ cnt[c - 'a'];
}
int i = 0, j = 0;
for (; j < m; ++ j) {
if (s[i] == t[j]) {
++ i;
} else if (cnt[t[j] - 'a'] > 0) {
-- cnt[t[j] - 'a'];
} else {
std::cout << "NO\n";
return;
}
}
if (i != n) {
std::cout << "NO\n";
} else {
std::cout << "YES\n";
}
}
D. 1-2-K Game
题意:博弈题。每次选\(1, 2, k\)三种数,谁先使得和为\(n\)谁赢。
打表发现如果\(k\)不是\(3\)的倍数,则\(n\)为\(3\)的倍数就输。如果\(k\)是\(3\)的倍数,则判断\(n \% (k + 1)\)的值,如果不是\(k\)且是\(3\)的倍数则输。
点击查看代码
void solve() {
int n, k;
std::cin >> n >> k;
if (k % 3 == 0) {
n = n % (k + 1);
if (n != k && n % 3 == 0) {
std::cout << "Bob\n";
} else {
std::cout << "Alice\n";
}
} else {
if (n % 3 == 0) {
std::cout << "Bob\n";
} else {
std::cout << "Alice\n";
}
}
}
E. Count The Rectangles
题意:\(n\)条平行于坐标轴的线段。求题目凑成的矩形数。
把平行于\(x\)轴的和平行于\(y\)轴的分开存。然后\(x\)轴按\(y\)坐标从小到大排序。\(y\)坐标按大的\(y\)排序。
那么可以枚举矩形的下边和上边,每次把\(y\)轴平行的线段中和下边相交的用队列存。然后枚举上边,因为已经按较大的\(y\)排序,所以可以把和上边不相交的弹出。用树状数组维护就行。假设和上边下边相交的有\(cnt\)个,那么就有\(\frac{cnt\times (cnt-1)}{2}\)个矩形。
点击查看代码
template <class T>
struct Fenwick {
int n;
std::vector<T> tr;
Fenwick(int _n) {
init(_n);
}
void init(int _n) {
n = _n;
tr.assign(_n + 1, T{});
}
void add(int x, const T &v) {
for (int i = x; i <= n; i += i & -i) {
tr[i] = tr[i] + v;
}
}
T query(int x) {
T res{};
for (int i = x; i; i -= i & -i) {
res = res + tr[i];
}
return res;
}
T sum(int l, int r) {
return query(r) - query(l - 1);
}
};
void solve() {
int n;
std::cin >> n;
using A = std::array<int, 3>;
std::vector<A> X, Y;
const int D = 5001;
for (int i = 0; i < n; ++ i) {
int x1, y1, x2, y2;
std::cin >> x1 >> y1 >> x2 >> y2;
x1 += D; y1 += D; x2 += D; y2 += D;
if (x1 == x2) {
if (y1 > y2) {
std::swap(y1, y2);
}
Y.push_back(A{x1, y1, y2});
} else {
if (x1 > x2) {
std::swap(x1, x2);
}
X.push_back(A{y1, x1, x2});
}
}
std::ranges::sort(X);
std::ranges::sort(Y, [&](A & a, A & b) {
return a[2] < b[2];
});
i64 ans = 0;
for (int i = 0; i < X.size(); ++ i) {
Fenwick<int> tr(D * 2);
std::queue<A> q;
for (auto & [x, y1, y2] : Y) {
if (y1 <= X[i][0]) {
tr.add(x, 1);
q.push(A{x, y1, y2});
}
}
for (int j = i + 1; j < X.size(); ++ j) {
while (q.size() && q.front()[2] < X[j][0]) {
tr.add(q.front()[0], -1);
q.pop();
}
int l = std::max(X[i][1], X[j][1]), r = std::min(X[i][2], X[j][2]);
if (l <= r) {
i64 cnt = tr.sum(l, r);
ans += cnt * (cnt - 1) / 2;
}
}
}
std::cout << ans << "\n";
}

浙公网安备 33010602011771号