12.10 CW 模拟赛 赛时记录

前言

最近发现只要每分钟都在做有意义的事就不算颓, 同理的, 这场考试只要每分钟都在想些事情, 也就不算

短期的主要目标就是利用好时间, 其他的问题我基本上已经解决了, 就是时间分配利用上的问题
所以就只抓时间分配, 这段时间先不去想别的, 就好好把时间利用起来, 不死磕, 不畏难, 利用好时间, 分配好

立个 flag , 这周不刷 B 站了

看题

粗看了一遍, 都不太好做, 好像给了好几道计数

1h+30min+30min+30min+1h10min

T1

思路#

转化题意, 要求把一个字符串拆分成若干段, 要求相邻子串至少有一个是倍数串

考虑 dp 来计数

朴素的想法是 fi,0/1 表示切分到了 i 位置, 其中最后一段是 / 不是倍数串的切分方案数

显然有

fi,0=Sj+1i fj,1

fi,1=Sj+1i fj,0

这个转移是 O(n2) 级别的, 只能通过 Subtask 1
加上预处理每个点之前的

那么怎么去优化时间复杂度呢?

仅仅找到每一个点对应的倍数串都已经 n2 了, 确实不好实现

考虑 Subtask 的打法, 居然不会???

判断是否能够成为倍数串好像还需要类似于高精度的方法, 毒瘤啊

预期得分 : 30pts

实现#

框架#

首先读入, 然后直接计算符合要求的倍数串, 刷表去做

关于怎么计算符合要求的倍数串:

  1. 枚举开头
  2. 从前往后, 先加上这个数再对 D 取余, 如果变成 0 就标记倍数串

代码#

稍微改了一下实现, 大样例都不想测

#include <bits/stdc++.h>
#define int long long
// #define FILE_IO
const int MAXN = 1020;

int T;
int D; std::string S; int n;

class Sol_Class
{
private:

public:
    bool IsMul[MAXN][MAXN];
    /*计算每个点为开头的倍数串*/
    void init()
    {
        for (int i = 1; i <= n; i++) { // 枚举起点
            int nownum = 0;
            for (int j = i; j <= n; j++) {
                nownum *= 10; nownum += S[j] - '0';
                nownum %= D;
                if (nownum) IsMul[i][j] = false; else IsMul[i][j] = true;
            }
        }
    }

    int f[MAXN][2];
    /*计算*/
    void solve()
    {
        memset(f, 0, sizeof(f));
        for (int i = 1; i <= n; i++) {
            f[i][0] = !IsMul[1][i], f[i][1] = IsMul[1][i];
            for (int j = 1; j < i; j++) {
                if (IsMul[j + 1][i]) f[i][1] += f[j][0] + f[j][1];
                else f[i][0] += f[j][1];
            }
        }

        printf("%lld\n", f[n][1] + f[n][0]);
    }
} Sol;

signed main()
{
#ifdef FILE_IO
    freopen("digit.in", "r", stdin);
    freopen("digit.out", "w", stdout);
#endif

    scanf("%lld", &T);
    while (T--) {
        std::cin >> S; scanf("%lld", &D); n = S.length(); S = ' ' + S;
        Sol.init();
        Sol.solve();
    }
}

T2

思路#

T1 确实不会做, 来开新题

很快就可以注意到, 之所以独特数的数量有限, 是因为对于 B 进制, 最多只能出现 B 种不同的数, 我们考虑直接排列组合这 B 种不同的数, 转化判断一下就可以得出答案, 这下可以有 50pts , 非常的赚

容易发现对于某些特殊情况, 从大到小枚举似乎可以骗到更多的分

期望得分 : 5070pts

实现#

框架#

直接 dfs

代码#

T3

思路#

前面两题连思路都没有也是抽象, 继续打吧

转化题意, 在环上相邻点之间可以选择是否建边, 要求建边之后, 对于 P 个点对联通
求最小的花费之和

考虑一个 O(nP) 的算法可以通过 40%

使用传统 trick , 枚举不使用一条边 O(n) , 然后在这种情况下做操作 O(P) , 解决

期望得分 : 40pts

T4

思路#

我觉得这种策略挺好的, 有节目效果

考虑设计一个 O(nm) 级别的算法通过 40%

怎么看不懂样例啊哥们???

真的看不懂啊???

算了直接暴力模拟即可, 每次乘起来, 但是怎么过不了样例???

那这题做不了, 摆了

posted @   Yorg  阅读(5)  评论(0编辑  收藏  举报
more_horiz
keyboard_arrow_up light_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示