2.11 CW 模拟赛 赛时记录

看题#

T1#

是一个代码长度不超过 500 B 的计数?
不是很理解

T2#

神秘括号串

T3#

构造, 没啥思路

T4#

不到啊


总的来说冲 T1 正解, 其他的骗暴力, 拼点高档上去就行了
状态完全没有回来, 不知道该怎么办

T1#

给了 35 min 思考

思路#

题意

  • 给定一个长为 nn 的排列 aa 和一个最初为空的大根堆
  • 进行 2n2n 次操作
    • 取出堆顶放入 bb 末尾
    • 取出 aa 开头放入堆

求最终得到的 bb 的种类数

先手动模拟找下性质
观察一组合法的 b 的性质

  • bi 中的数在原串中的位置为 posi , 那么对于 pos 中的逆序对 (bi,bj) , 有 bi>bj
  • posi 可以看做几个公差为 1 的下降拼起来, 例如
    321 54 876
    但是要求满足第一条, 也就是说每一段 p1p2p3 , 需要满足 ap1>ap2>ap3>

所以我们继续面向数据

1 4 2 3

对应位置

1 2 | 3 4

我们可以添加一些分割线, 然后依次摆放

发现一组明显的反例 2 3 1
也就是说 3 可以放在下降串 2 1 中间


完全没时间了, 脑子丢掉打暴力

暴力代码#

#include <bits/stdc++.h>
const int MOD = 8580287;
const int MAXN = 1020;

namespace calc {
    int add(int a, int b) { return a + b > MOD ? a + b - MOD : a + b; }
    int mul(int a, int b) { return (a * b * 1ll) % MOD; }
    int sub(int a, int b) { return a - b < 0 ? a - b + MOD : a - b; }
    void addon(int &a, int b) { a = add(a, b); }
    void mulon(int &a, int b) { a = mul(a, b); }
} using namespace calc;

int n;
int a[MAXN];

class subtask5
{
private:
    int dp[MAXN << 1][MAXN];

public:
    void solve() {
        memset(dp, 0, sizeof dp);
        dp[0][0] = 1;
        for (int i = 1; i <= 2 * n; i++) {
            for (int j = 0; j <= n; j++) {
                if (j != 0) addon(dp[i][j], dp[i - 1][j - 1]);
                if (j != n) addon(dp[i][j], dp[i - 1][j + 1]);
            }
        }
        printf("%d", dp[n * 2][0]);
    }
} s5;

class subtask12
{
private:
    int ans = 0;
    int tmp[MAXN], b[MAXN];
    std::priority_queue<int> heap;

public:
    void solve() {
        for (int i = 1; i <= n; i++) tmp[i] = i;
        do {
            for (int i = 1; i <= n; i++) b[i] = tmp[i];
            while (!heap.empty()) heap.pop();

            int ahs = 1, bhs = 1;
            while (ahs <= n && bhs <= n) {
                while ((ahs <= n && bhs <= n) && (heap.empty() || heap.top() != b[bhs])) heap.push(a[ahs++]);
                while ((ahs <= n + 1 && bhs <= n + 1) && (!heap.empty() && heap.top() == b[bhs])) heap.pop(), bhs++;
            }

            if (bhs == n + 1) addon(ans, 1);

        } while(std::next_permutation(tmp + 1, tmp + n + 1));

        printf("%d", ans);
    }
} s12;

int main()
{
    scanf("%d", &n); for (int i = 1; i <= n; i++) scanf("%d", &a[i]);

    /*特殊性质*/
    bool sub4 = true, sub5 = true;
    for (int i = 1; i <= n; i++) {
        if (a[i] != n - i + 1) sub4 = false;
        if (a[i] != i) sub5 = false;
    }
    // sub5 = false;

    if (sub4) { printf("1"); return 0; }
    if (sub5) { s5.solve(); return 0; }

    /*30pts 诈骗*/
    s12.solve();

    return 0;
}

寻思了一下 T2 打不出来 , 把后面题读了方便补题之后直接来冲 T1

T2#

趋势

先把后面暴力打了, 这场寄了

思路#

首先我们考虑怎么计算一个括号串中, 有多少句刀语

一些想法

好像用类似括号树的结构, 然后合并树上点可以很快地做出来, 但是那大概是考完之后的事情了, 现在只能考虑纯暴力, 主要原因是不会建树

打半天一直错, 破防了直接删了赛后重构

T3#

纯纯的方便补题所以开, 今天不计入 rank , 太神经了

思路#

好吧这个是真的不会

T4#

思路#

不难发现可以跑房子之间的距离, 然后转化成一个什么什么问题, 没学过连名字都记不到, 好像叫最小流什么什么的

不知道复杂度是多少, 但是房子之间肯定不能 O(pnm) 去做, 要考虑优化
理论上每个点只和与他最近的点连边最优秀, 所以染一遍色就行了

然后跑什么什么算法, 没学过不可能优化

总结#

贤者时刻

以后打比赛一定要严格按照策略, 今天可能本来能试着做一下后面的题, 因为死磕的原因去世了

posted @   Yorg  阅读(5)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示