zoukankan      html  css  js  c++  java
  • 2020牛客寒假算法基础集训营3

    题目链接:https://ac.nowcoder.com/acm/contest/3004

    假算法集训营第3期,快来看看你有哪些基础知识还不会吧!~

    这几天有时间先补图论的坑,再补LCT吧,字符串和几何目前只能选择相信队友。

    A - 牛牛的DRB迷宫I

    水题

    G题的不带修形式。甚至从这道题已经可以知道下一道题的线段树要怎么维护了。

    题意:有一个01串,求每对1之间的距离和。

    题解:每右移一位,总的距离就增加左侧的1的数量。在遇到1的时候统计“它作为右边的1时”的贡献。

    char g[100005];
    void test_case() {
        int n;
        scanf("%d%s", &n, g + 1);
        ll ans = 0, sum = 0;
        int cnt = 0;
        for(int i = 1; i <= n; ++i) {
            if(g[i] == '1') {
                ans += sum;
                ++cnt;
            }
            sum += cnt;
            if(sum >= MOD)
                sum -= MOD;
        }
        ans %= MOD;
        printf("%lld
    ", ans);
    }
    

    H - 牛牛的k合因子数

    题意:给一个n<=1e5,求范围中有多少个数恰好有k个合数因子。

    题解:由于 (sumlimits_{i=1}^{n}lfloorfrac{n}{i} floor ~ O(nlogn)) ,直接暴力求。

    const int MAXN = 1e5;
    int p[MAXN + 5], ptop;
    bool pn[MAXN + 5];
    
    void sieve() {
        int n = MAXN;
        pn[1] = 1;
        for(int i = 2; i <= n; i++) {
            if(!pn[i])
                p[++ptop] = i;
            for(int j = 1; j <= ptop; j++) {
                int t = i * p[j];
                if(t > n)
                    break;
                pn[t] = 1;
                if(i % p[j] == 0)
                    break;
            }
        }
    }
    
    int cnt[MAXN + 5];
    int ans[MAXN + 5];
    
    void test_case() {
        sieve();
        int n, m;
        scanf("%d%d", &n, &m);
        for(int i = 2; i <= n; ++i) {
            if(pn[i]) {
                for(int j = i; j <= n; j += i)
                    ++cnt[j];
            }
        }
        for(int i = 1; i <= n; ++i)
            ++ans[cnt[i]];
        while(m--) {
            int k;
            scanf("%d", &k);
            printf("%d
    ", ans[k]);
        }
    }
    

    *D - 牛牛与二叉树的数组存储

    一开始觉得:“什么垃圾题,怎么花钱买了这种题。”

    然后就段错误了。事实证明不能够小看和轻视。

    题意:给一棵满二叉树,上面恰好有[1,m]号节点,按顺序输出他们的父亲和孩子们。

    题解:模拟,然后小心越界。

    int data[200005], pos[200005];
    
    void test_case() {
        int n, m = 0;
        scanf("%d", &n);
        memset(data, -1, sizeof(data));
        for(int i = 1; i <= n; ++i) {
            scanf("%d", &data[i]);
            if(data[i] != -1) {
                pos[data[i]] = i;
                m = max(m, data[i]);
            }
        }
        printf("The size of the tree is %d
    ", m);
        printf("Node %d is the root node of the tree
    ", data[1]);
        for(int i = 1; i <= m; ++i)
            printf("The father of node %d is %d, the left child is %d, and the right child is %d
    ", i, data[pos[i] / 2], data[pos[i] * 2], data[pos[i] * 2 + 1]);
    }
    

    *C - 牛的数组越位

    题意:告诉你C++中二维数组中中括号的运算规则,以及某编译器对此ub的处理。要求模拟给数组赋值,检测是否有ub甚至真正的re。

    题解:按题意模拟。

    总结:没写过这种**bug就不知道自己这么**,居然连

        if(0 <= x < n)
            statement;
    

    这种表达都出来了。其实编译器已经给出了警告,记得在新电脑上调好编译器并打开 -Wall 开关。

    KisekiPurin.cpp|69|warning: comparisons like 'X<=Y<=Z' do not have their mathematical meaning [-Wparentheses]|
    
    int a[1000005];
    void test_case() {
        int n, m, p;
        scanf("%d%d%d", &n, &m, &p);
        memset(a, 0, sizeof(a[0]) * (n * m));
        bool ub = 0, re = 0;
        while(p--) {
            int x, y, v;
            scanf("%d%d%d", &x, &y, &v);
            if(re)
                continue;
            ll t = 1ll * x * m + y;
            if(0 <= x && x < n) {
                if(0 <= y && y < m)
                    a[t] = v;
                else {
                    ub = 1;
                    if(0 <= t && t < n * m)
                        a[t] = v;
                    else
                        re = 1;
                }
            } else {
                ub = 1;
                if(0 <= t && t < n * m)
                    a[t] = v;
                else
                    re = 1;
            }
        }
        if(re) {
            puts("Runtime error");
            return;
        }
        int top = 0;
        for(int i = 0; i < n; ++i) {
            for(int j = 0; j < m; ++j)
                printf("%d%c", a[top++], " 
    "[j == m - 1]);
        }
        if(ub)
            puts("Undefined Behaviour");
        else
            puts("Accepted");
    }
    
  • 相关阅读:
    win7下cygwin命令行颜色和中文乱码解决
    maven mirror
    maven命令
    dubbo获取错误ip
    eclipse netbeans 代码模板
    windows下配置Groovy
    c++ 载入内存中dll ,以及内存注入
    表达式求值的 计算器
    vc 编译器的一些精典报错
    内联汇编实现 memcpy 和 memset
  • 原文地址:https://www.cnblogs.com/KisekiPurin2019/p/12286122.html
Copyright © 2011-2022 走看看