2026.2.25总结

2026.2.25总结

题目 A B C D
估分 100 100 100 0
实际 80 38 100 0

太可怕了。

A

就是模拟,但是我因为少打一个等于号,所以挂了20。

#include <bits/stdc++.h>
using ll = long long;
#define f first
#define s second
const int inf = (1 << 30) - 1;
const ll INF = 1ll << 62;

int n, x, cnt = 1, len;

int main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr), std::cout.tie(nullptr);
    std::cin >> n >> x;
    std::cout << "+---------------------+\n";
    std::cout << '|';
    for (int i = 1; i < x; i++) std::cout << "...", len += 3;
    while (cnt <= n) {
        len += 3;
        if (cnt >= 10) std::cout << "." << cnt;
        else std::cout << ".." << cnt;
        cnt++;
        if (len == 21) {
            std::cout << "|\n", len = 0;
            if (cnt <= n) std::cout << '|';
        }
    }
    if (len) {
        while (len != 21) std::cout << "...", len += 3;
        std::cout << "|\n";
    }
    std::cout << "+---------------------+\n";
}

B

也是模拟,但是我因为下标弄错了导致挂了分。

做法就是对于每一种情况,用一个 bitset 存储一下 。

如果当前的数已经被标记过,就直接输出 GRESKA

否则,就输出 OK

#include <bits/stdc++.h>

using ll = long long;
using ull = unsigned long long;
using ui = unsigned int;
using i128 = __int128;
using db = double;
#define rep(i, a, b) for (int i = a; i <= b; i++)
#define frep(i, b, a) for (int i = b; i >= a; i--)
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define pf push_front
#define mp make_pair
#define s second
#define f first
const int inf = (1 << 30) - 1;
const ll INF = 1LL << 62LL;
const int mod = 998244353;
const db eps = 1e-9;
std::mt19937_64 rng(std::chrono::system_clock::now().time_since_epoch().count());

const int N = 20;
int a[N][N];
std::string s;

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    for (int i = 0; i < 9; i++) {
        std::cin >> s;
        if (!(i % 3)) std::cin >> s;
        s.erase(s.begin()), s.erase(s.begin() + 3), s.erase(s.begin() + 6), s.erase(s.begin() + 9);
        rep(j, 0, 8) if (s[j] == '.') a[i][j] = 0;
        else a[i][j] = s[j] - '0';
    }
    rep(i, 0, 8) {
        std::bitset<10> vis;
        rep(j, 0, 8)  {
            if (a[i][j] && vis[a[i][j]]) return std::cout << "GRESKA\n", 0;
            vis[a[i][j]] = true;
        }
    }
    rep(i, 0, 8) {
        std::bitset<10> vis;
        rep(j, 0, 8) {
            if (a[j][i] && vis[a[j][i]]) return std::cout << "GRESKA\n", 0;
            vis[a[j][i]] = true;
        }
    }
    rep(i, 0, 8) {
        std::bitset<10> vis;
        rep(j, 0, 8) {
            if (a[i / 3 * 3 + j / 3][i % 3 * 3 + j % 3] && vis[a[i / 3 * 3 + j / 3][i % 3 * 3 + j % 3]]) return std::cout << "GRESKA\n", 0;
            vis[a[i / 3 * 3 + j / 3][i % 3 * 3 + j % 3]] = true;
        }
    }
    std::cout << "OK\n";
}

C

就是大炮,但是是三维的。

考虑 \(dp_{i,\ j,\ 0/1}\) 表示考虑到了 \(a\) 中的第 \(i\) 个, \(b\) 中的第 \(j\) 个,当前是考虑 \(a\) 还是考虑 \(b\)

首先想 \(dp_{i,\ j,\ 0}\)

  • 如果从 \(dp_{i - 1,\ j,\ 0}\) 转移过来,就要看 \(a_{i−1}\)\(a_i\) 一不一样,如果一样加 \(2\) ,不一样加 \(1\)
  • 如果从 \(dp_{i - 1,\ j,\ 1}\) 转移过来,就要看 \(a_i\)\(b_j\) 一不一样,一样加 \(2\) ,不一样加 \(1\)

同理,\(dp_{i,\ j,\ 1}\) 的状态转移方程也很好想了,也是类似的,但是由 \(dp_{i,\ j - 1,\ 0}\) 转移过来的是看 \(b_{i - 1}\)\(b_i\) 一不一样。

#include <bits/stdc++.h>
using ll = long long;
#define f first
#define s second
const int inf = (1 << 30) - 1;
const ll INF = 1ll << 62;

const int N = 5010;
int n, m, a[N], b[N], dp[N][N][2];

int main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr), std::cout.tie(nullptr);
    std::cin >> n;
    for (int i = 1; i <= n; i++) std::cin >> a[i];
    std::cin >> m;
    for (int i = 1; i <= m; i++) std::cin >> b[i];
    for (int i = 1; i <= n; i++) dp[i][0][0] = dp[i - 1][0][0] + 1 + (a[i] == a[i - 1]), dp[i][0][1] = inf;
    for (int i = 1; i <= m; i++) dp[0][i][1] = dp[0][i - 1][1] + 1 + (b[i] == b[i - 1]), dp[0][i][0] = inf;
    for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) {
        dp[i][j][0] = std::min(dp[i - 1][j][0] + 1 + (a[i] == a[i - 1]), dp[i - 1][j][1] + 1 + (a[i] == b[j]));
        dp[i][j][1] = std::min(dp[i][j - 1][0] + 1 + (a[i] == b[j]), dp[i][j - 1][1] + 1 + (b[j] == b[j - 1]));
    }
    std::cout << std::min(dp[n][m][0], dp[n][m][1]) << '\n';
}

D

单调队列加入元素时一定要写while!!!

单调队列加入元素时一定要写while!!!

单调队列加入元素时一定要写while!!!

因为这个痛失100pts

之前都调出来了,这次却没有调出来。

就是单调队列板子题。

注意到这个很像滑动窗口。

但是是二维的。

我们再次发现:二维只需要横着来一次,竖着来一次就行了。

#include <bits/stdc++.h>
using ll = long long;
#define f first
#define s second
const int inf = (1 << 30) - 1;
const ll INF = 1ll << 62;

const int N = 4010;
struct queue {
    int n, cnt = 0;
    std::deque<std::pair<int, int>> q;
    queue(int _n) {n = _n;}
    void push(int x) {
        while (!q.empty() && x > q.back().f) q.pop_back();
        q.push_back({x, ++cnt});
        while (q.front().s + n <= cnt) q.pop_front();
    }
    int front() {
        return q.front().f;
    }
};
int n, m, r, c, a[N][N], b[N][N];

int main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr), std::cout.tie(nullptr);
    std::cin >> n >> m;
    for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) std::cin >> a[i][j];
    std::cin >> r >> c;
    for (int i = 1; i <= n; i++) {
        queue q(c);
        for (int j = 1; j <= m; j++) {
            q.push(a[i][j]);
            if (j >= c) a[i][j - c + 1] = q.front();
        }
    }
    // for (int i = 1; i <= n - r + 1; i++) for (int j = 1; j <= m - c + 1; j++) std::cout << b[i][j] << " \n"[j == m - c + 1];
    for (int i = 1; i <= m - c + 1; i++) {
        queue q(r);
        for (int j = 1; j <= n; j++) {
            q.push(a[j][i]);
            if (j >= r) a[j - r + 1][i] = q.front();
        }
    }
    for (int i = 1; i <= n - r + 1; i++) for (int j = 1; j <= m - c + 1; j++) std::cout << a[i][j] << " \n"[j == m - c + 1];
}

posted @ 2026-02-25 21:44  yixinc  阅读(11)  评论(0)    收藏  举报