zoukankan      html  css  js  c++  java
  • 2019.10.24模拟赛

    T1 古代龙人的谜题

    Mark Douglas 是一名调查员。他接受了「调查古代龙人」的任务。经过千辛万苦,Mark 终于找到了一位古代龙人。Mark 找到他时,他正在摆弄一些秘药,其中一些药丸由于是从很久以前流传下来的,发出了独特的光泽。古代龙人告诉了 Mark 一些他想知道的事情,看了看手中的秘药,决定考一考这位来访者。
    古代龙人手中共有(n)粒秘药,我们可以用(1)表示「古老的秘药」,其余的用(0)表示。他将它们排成一列。古代龙人认为平衡是美的,于是他问 Mark 能选出多少个「平衡的区间」。「平衡的区间」是指首先选出一个区间([L,R]),在它内部选出一个中间点(mid),满足(L < mid < R),(mid)是「古老的秘药」,且区间([L,R])([mid,R])中「古老的秘药」个数相等。

    SOV

    可行的区间一定有奇数个1,考虑统计1的贡献。
    先记录每个一1右侧的0的个数,之后分奇偶求和。
    奇数1都可以和奇数1配对,偶数1都可以和偶数1配对,对答案产生贡献。
    每个单独的1单独计算答案即可。

    int main() {
        int Case;
        register int n, m = 0;
        register long long ans = 0;
        poread(Case);
        poread(n);
        for (register int i = 1; i <= n; ++i) a[i] = g(), m += a[i];
        for (register int i = n, j = m, sum = 0; i && j; --i) a[i] ? ++sum, cnt[j] = sum, sum = 0, --j : ++sum;
        register long long lr[2] = { 0, 0 };
        for (register int i = 1; i <= m; ++i) lr[i & 1] += cnt[i];
        for (register int i = 1, sum = 0, j = 1; i <= n; ++i)
            a[i] ? ++sum, lr[j & 1] -= cnt[j], ans += (long long)(sum - 1) * (cnt[j] - 1) + sum * lr[j & 1],
                sum = 0, ++j : ++sum;
        printf("%lld", ans);
    }
    

    T2 交错的字符串

    Mark Douglas 是一名律师。他的客户 Yuri Ball 在一场车祸中不幸去世。为了帮助 Yuri 的亲属拿到他的遗产, Mark 需要得到一个密码。在 Yuri 的笔记本上,有一个长为 的只包含小写字母的字符串, Mark 知道密码恰好是将这个字符串分解为两个长度为(n)的子序列且它们构成的字符串恰好相反的方案数。我们认为两种分解方法是不同的,当且仅当两个下标集合构成的集合$ {S1,S2}(是不同的,注意) {S1,S2}$ 和 $ {S2,S1}$ 我们认为是相同的分解方法。如 cabaacba 的合法分解共有 cabaacba 和 cabaacba 两种。 Mark 希望你能帮助他计算出密码,事成之后他决定分给你 six million five hundred thousand dollars 并邀请你去柬埔寨度假。

    SOV

    折半搜索。
    搜索左半可以分成的,放到(hash)记录,搜索右半部分记录答案。

    #include <bits/stdc++.h>
    using namespace std;
    short n;
    long long ans;
    char s[38];
    unordered_map<string, long long> mp;
    bool v[38];
    inline void dfs1(short now) {
        if (now == n + 1) {
            string s1, s2;
            for (register int i = 1; i <= n; ++i)
                if (v[i])
                    s1 += s[i];
            for (register int i = n; i; --i)
                if (!v[i])
                    s2 += s[i];
            ++mp[s1 + '|' + s2];
            return;
        }
        v[now] = 0;
        dfs1(now + 1);
        v[now] = 1;
        dfs1(now + 1);
    }
    inline void dfs2(short now) {
        if (now == 2 * n + 1) {
            string s1, s2;
            for (register int i = n + 1; i <= 2 * n; ++i)
                if (v[i])
                    s1 += s[i];
            for (register int i = 2 * n; i > n; --i)
                if (!v[i])
                    s2 += s[i];
            ans += mp[s2 + '|' + s1];
            return;
        }
        v[now] = 0;
        dfs2(now + 1);
        v[now] = 1;
        dfs2(now + 1);
    }
    int main() {
        cin >> n;
        cin >> s + 1;
        dfs1(1);
        dfs2(n + 1);
        cout << ans / 2 << endl;
    }
    
  • 相关阅读:
    github 访问速度慢 的解决+个人理解
    phpstorm 编辑器进行自动的注释添加
    输入框只能输入数字(最好用)
    数组去重(根据对象属性去重)
    mac安装Homebrew和 tree
    vue中 .sync 的作用
    打包 vue 组件为 webcomponent
    Android开发之SharedPreferences
    Android开发之SharedPreferences扩展以及File
    Android 开发之SQLite基础
  • 原文地址:https://www.cnblogs.com/Shiina-Rikka/p/11745198.html
Copyright © 2011-2022 走看看