• 7.29 Test——Math Theory 1


    T1:

    1 菠萝包

    1.1 Description
    萨塔妮亚正在吃菠萝包,可她不知道菠萝包被人涂上了芥末。
    菠萝包表面烤出了一个n * m 的网格,其中有一些格子涂上了芥末。
    萨塔妮亚会一口咬下其中k * k 大小的一个正方形网格,这k * k格中如果有一格有芥末,萨塔妮亚就会呛到无法自拔。
    你想知道有多少种情况她会被呛到。

    1.2 Task
    1.2.1 Input
    第一行三个数n, m, k;
    接下来一个nm 的01 矩阵表示菠萝包上的情况,1 表示涂了芥末。

    1.2.2 Output
    输出一个整数表示萨塔妮亚会吃到芥末的情况数。

    1.3 Sample
    1.3.1 Input
    4 4 2
    1000
    0100
    0000
    0001
    1.3.2 Output
    5

    1.4 Constraint
    对于30% 的数据,n,m <= 30;
    对于100% 的数据,n, m <= 1000,k <=  min(n, m)。

    解析:

      签到题, 二维前缀和预处理,计算k*k的矩阵和是否为0

     代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1005;
    
    int n, m, k, s[maxn][maxn], ans;
    
    int main()
    {
        freopen("a.in", "r", stdin);
        freopen("a.out", "w", stdout);
        scanf("%d%d%d", &n, &m, &k);
        for(int i = 1; i <= n; ++i)
            for(int j = 1; j <= m; ++j)
            {
                char c=getchar();
                while(c<'0'||c>'9')     c = getchar();
                s[i][j] = c - '0';
            }
        for(int i = 1; i <= n; ++i)
            for(int j = 1; j <= m; ++j)
            {
                s[i][j] += s[i-1][j] + s[i][j-1] - s[i-1][j-1];
                if(i >= k && j >= k)
                {
                    int res = s[i][j] - s[i-k][j] - s[i][j-k] + s[i-k][j-k];
                    if(res)
                        ans ++;
                }
            }
        printf("%d", ans);
        return 0;
    }
    a

    T2:

    2 无聊

    2.1 Description
    薇奈把珈百璃的电脑收走了,无聊的珈百璃只好躺在床上数数。
    珈百璃想:一个数有很多很多约数,这些约数又有很多很多约数,那一个数就有很多约数的约数。
    珈百璃想:12 有多少个约数的约数呢?12 的约数有1,  2,  3,  4,  6, 12,这些数分别有1,  2,  2,  3,  4,  6 个约数,那12 有18 个约数的约数。
    珈百璃想:1 ~ n 的数里哪个数的约数的约数个数最多呢?
    没了电脑的珈百璃数不出来(虽然她一有电脑就会打网游),于是她请求你帮忙。

    2.2 Task
    2.2.1 Input
    一行一个正整数n。
    2.2.2 Output
    输出共两行。
    第一行一个正整数表示约数的约数个数最多的数,如果有多个输出最
    小的。
    第二行一个正整数表示这个数的约数的约数的个数

    2.3 Sample I
    2.3.1 Input
    15
    2.3.2 Output
    12
    18

    2.4 Sample II
    2.4.1 Input
    114514
    2.4.2 Output
    110880
    3402

    2.5 Constraint
    测试点n 

    1 10
    2 103
    3 105
    4 107
    5 109
    6, 7 1013
    8, 9, 10 1018



    解析:

      试时最后打的表,结果没时间跑样例, 就没发现要加1, 普通打表可以打40pts, 当然高手可以打出70pts, 这我也不知道该怎么打,我太菜了

       考虑到一个为 ∏piri的数(其中pi为互不相同的质数), 它的约数个数为 ∏(ri + 1), 那么由乘法分配律可以得到,约数的约数个数为 ∏(1 + 2 + … + (ri + 1)), 即 ∏((ri + 2)* (ri + 1) /  2)

      如何求答案呢,由于答案要求相同情况下输出较小的一个, 考虑答案的质因数分解, 当pi单增时,ri一定不严格单减 , 那么枚举ri的序列即可,pi的个数也并不多,复杂度可以接受

     代码:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    int pri[17] = {0,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53};
    ll n, ans1, ans2;
    
    void dfs(int x, ll now, ll res, int pre)
    {
        if(res > ans2)
        {
            ans1 = now;
            ans2 = res;
        }
        else if(res == ans2 && now < ans1)
            ans1 = now;
        if(x == 17)    return ;
        for(int i = 1; i <= pre && now <= n / pri[x] && now * 1LL * pri[x] <= n; ++i)
        {
            now *= 1LL * pri[x];
            dfs(x + 1, now, res * 1LL * (i + 1) * (i + 2) / 2, i);
        }
    }
    
    int main()
    {
        freopen("b.in", "r", stdin);
        freopen("b.out", "w", stdout);
        scanf("%lld", &n);
        dfs(1, 1, 1, 60);
        printf("%lld
    %lld", ans1, ans2);
        return 0;
    }
    b

    T3:

    3 密道

    3.1 Description
    珈百璃在打副本时,走到一个奇怪的密道。密道由n+1条横道和n+1条纵道交叉形成,这些横纵道分别编号为0 到n。
    横道和纵道相交的地方都有路口,姑且把第i 条横道和第j 条纵道交错的路口叫做路口(i; j)。
    有的路口有怪物,经过珈百璃一段时间的发掘,珈百璃发现了刷怪的秘密:
       所有路口(i, 0) 和路口(0, i) 一定有怪物。
       对于其他路口(i, j),如果(i - 1, j) 和(i, j - 1) 都有怪物或者都没有怪物,那么这个路口也没有怪物;否则有。
    珈百璃想通过这个副本,自然需要先知道这些密道里有多少怪物了。
    那么,到底有多少路口有怪物呢?

    3.2 Task
    3.2.1 Input
    一行一个正整数n。
    3.2.2 Output
    一行一个正整数表示有怪物的路口数量。

    3.3 Sample I
    3.3.1 Input
    3
    3.3.2 Output
    9

    3.4 Sample II
    3.4.1 Input
    114514
    3.4.2 Output
    119562749

    3.5 Constraint
    对于30% 的数据,n <= 3000;
    对于另外30% 的数据,n 是形如2k  - 1 的数;
    对于100% 的数据,n  <= 109

    解析:

      其实可以打表找规律,然后就发现,有1的地方(有怪物的地方)组成了长相相似三角形,三角形的边长都是2的次幂, 三角形内1的个数都是3的次幂, 三角形的个数取决于当前的边长, 与上一个三角形的边长和个数, 这个不太能说清,可以打个表体会一下

      然后来一发正解(From Solution):

      可以发现如果把这个矩阵旋转45 度就是杨辉三角的递推式,也就是说(i, j) 的状态是C(i + j, j) mod 2。
      在模2 意义下由Lucas 定理C(i + j, j)只在j 的二进制表示是i+j 的子集时为1,等价于i 和j 的二进制表示没有任何一位同时为1,直接枚举最高位算或者数位dp 解决。

     代码(非正解):

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    ll n, ans;
    ll pw3[40];
    
    void dfs(ll rest, ll num, int len)
    {
        if(rest == 0)    return ;
        for(int i = len - 1; i >= 0; --i)
            if(1LL * (1<<i) <= rest)
            {
                ll now = (1<<(len-i)) * num/2;
                ans += 1LL * 2 * now * pw3[i];
                dfs(rest - (1<<i), now, i);
                return ;
            }
    }
    
    int main()
    {
        freopen("c.in", "r", stdin);
        freopen("c.out", "w", stdout);
        scanf("%lld", &n);
        n ++;
        pw3[0] = 1;
        for(int i = 1; i <= 32; ++i)
            pw3[i] = 1LL * pw3[i-1] * 3;
        int len = log(n)/log(2);
        ans = pw3[len];
        dfs(n - (1<<len), 2, len);
        printf("%lld
    ", ans);
        return 0;
    }
    c
  • 相关阅读:
    Windows下的RabbitMQ安装:RabbitMQ_Service安装
    [Java]private, public,protected,friendly的区别(转载)一下子就记住了
    mysql的一些sql用法
    set(string str)变量传参为int的问题
    eclipse插件开发常见的问题及解决办法
    eclipse 内存溢出
    如何在一台机器上运行2个Tomcat
    eclipse svn使用
    eclipse遇到的异常
    oracle学习
  • 原文地址:https://www.cnblogs.com/Joker-Yza/p/11266485.html
Copyright © 2020-2023  润新知