| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2415 人关注过本帖, 2 人收藏
标题:呼叫版主,貌似是数学题
只看楼主 加入收藏
a1004573547
Rank: 2
等 级:论坛游民
帖 子:78
专家分:25
注 册:2013-3-11
结帖率:40%
收藏(2)
已结贴  问题点数:10 回复次数:20 
呼叫版主,貌似是数学题
两个数组a和b
长度分别为n m
他们组成一个矩阵f fij=ai*bj
问这个矩阵中有多少个子矩阵里元素之和是c的倍数
输入格式

第一行一个正整数T(T<=20),代表测试数据的组数。
每组数据有3行。
第一行三个正整数n,m,c
第二行有n个正整数a1,a2...,an
第三行有m个正整数b1,b2...,bm
数据范围:
1<=n,m<=30000
1<=ai,bi<=30000
1<=c<=30000


输出格式

每组数据输出一行。

输入样例
2
2 3 5
2 3
1 3 4
2 3 11
2 3
1 3 4
输出样例
6
0
搜索更多相关主题的帖子: 数学题 正整数 元素 
2014-01-23 09:04
a1004573547
Rank: 2
等 级:论坛游民
帖 子:78
专家分:25
注 册:2013-3-11
收藏
得分:0 
讨论下,还没什么想法
2014-01-23 09:05
so_love
Rank: 13Rank: 13Rank: 13Rank: 13
等 级:蒙面侠
威 望:7
帖 子:812
专家分:4151
注 册:2013-11-25
收藏
得分:4 
智商有点低。没看明白什么意思

一花一世界、一叶一追寻、片片花叶落、情系何人身。
2014-01-23 09:33
a1004573547
Rank: 2
等 级:论坛游民
帖 子:78
专家分:25
注 册:2013-3-11
收藏
得分:0 
图片附件: 游客没有浏览图片的权限,请 登录注册
2014-01-23 10:35
a1004573547
Rank: 2
等 级:论坛游民
帖 子:78
专家分:25
注 册:2013-3-11
收藏
得分:0 
图片附件: 游客没有浏览图片的权限,请 登录注册
2014-01-23 10:36
pangshch
Rank: 10Rank: 10Rank: 10
等 级:青峰侠
威 望:2
帖 子:443
专家分:1966
注 册:2013-4-9
收藏
得分:4 
程序代码:
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int i, j, k, p, q, r;  // for循环使用
    int n, m, c;
    int t;
    int s;                 // 求和
    int cnt;               // 子矩阵个数
    int *a, *b, *x, **f;    // 元素的个数有30000个, 所以都用动态分配内存  

    scanf("%d", &t);
    while (t-- > 0) {
        cnt = 0;
        scanf("%d%d%d", &n, &m, &c);
        a = (int *)malloc(n*sizeof(int));    
        b = (int *)malloc(m*sizeof(int));
        x = (int *)malloc(m*sizeof(int));
        f = (int **)malloc(n*sizeof(int *));
        if (a == NULL || b == NULL || x == NULL || f == NULL)
            exit(1);
        for (i = 0; i < n; i++) {
            f[i] = (int *)malloc(m*sizeof(int));
            if (f[i] == NULL)
                exit(1);
        }
      // 三个数组的值
        for (i = 0; i < n; i++)
            scanf("%d", &a[i]);
        for (i = 0; i < m; i++)
            scanf("%d", &b[i]);
        for (i = 0; i < n; i++)
            for (j = 0; j < m; j++)
                f[i][j] = a[i] * b[j];

    
        for (r = 0; r < n; r++) {
            for (i = 0; i < m; i++)
                x[i] = 0;
            for (i = r; i < n; i++) {
                for (j = 0, k = 0; j < m; j++)
                    x[k++] += f[i][j];
                for (p = 0; p < m; p++) {
                    s = x[p];
                    if (s%c == 0)
                        cnt++;
               
                    for (q = p + 1; q < m; q++) {
                        s += x[q];
                        if (s%c == 0)
                            cnt++;
                   
                    }
                }
            }
        }
        printf("%d\n", cnt);
    }
    free(a);     
    free(b);
    free(x);
    for (i = 0; i < m; i++)
        free(f[i]);
    free(f);
    return 0;
}

思路就是: 和冒泡排序的思路是一样的, 只是把排序变成求和.
 把行和列分开考虑.
分别对行和列进行求和,
例如第一个:
1. 对第一行求和, 保存到x数组
2.对行求和, 结果与c求模  
3.对第一行和第二行求和, 保存到x数组.
4. 重复2.
5. 对前三行求和..直到最后一行.
6. 最后一行之后, x数组重新初始化为0, 再从第二行开始. (冒泡排序的算法)

我感觉说得不是很清楚, 样例测试OK,
可以讨论....


[ 本帖最后由 pangshch 于 2014-1-23 12:35 编辑 ]
2014-01-23 12:10
pangshch
Rank: 10Rank: 10Rank: 10
等 级:青峰侠
威 望:2
帖 子:443
专家分:1966
注 册:2013-4-9
收藏
得分:0 
没有释放内存, 我改一下...
2014-01-23 12:33
a1004573547
Rank: 2
等 级:论坛游民
帖 子:78
专家分:25
注 册:2013-3-11
收藏
得分:0 
看一下m和n  那么大  有没有nlogn及以下时间复杂度的算法
你那个已经超n^2了
        设sumA[i]表示数组a前i项和,sumB[i]表示数组b前i项的和。
    递推可得以(i,j)为左上顶点,(x,y)为右下顶点的子矩阵,它的所有元素之和为(sumA[x]-sumA[i-1])*(sumB[y]-sumB[j-1])。
    枚举所有(x,i)求出(sumA[x]-sumA[i-1])%c的值,用hashA记录,hashA[k1]表示(sumA[x]-sumA[i-1])%c=k1的(x,i)有多少对。
    枚举所有(y,j)求出(sumB[y]-sumB[j-1])%c的值,用hashB记录,hashB[k2]表示(sumA[y]-sumA[j-1])%c=k2的(y,j)有多少对。
    暴力枚举k1,k2,若k1*k2%c=0,那么答案加上hashA[k1]*hashB[k2]。
    时间复杂度为O(n^2+c^2)。
对上面进行优化,假设枚举k1,设gcd(k1,c)=d,d’=c/d,那么k2必须是d’的倍数才会使得k1*k2%c=0,所以第二维只要枚举d’、2*d’、3*d’……即可,其实就是一个筛法的应用。复杂度为O(n^2+ clogc)。
2014-01-23 17:46
beyondyf
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:103
帖 子:3282
专家分:12654
注 册:2008-1-21
收藏
得分:4 
好大的规模。楼主玩的题目等级都很高啊。我目前的想法大概只能做到O(n^2 + m^2),想来是要超时的。还得再想想呵呵。

原题在哪,我想去看看。

重剑无锋,大巧不工
2014-01-23 20:25
a1004573547
Rank: 2
等 级:论坛游民
帖 子:78
专家分:25
注 册:2013-3-11
收藏
得分:0 
还是学校oj。。。有人说CF上有类似的
原题: LRC是SCAU_ACM校队的主席,职业生涯为校队作过很多贡献。除此之外,LRC也被各路ACMER奉为RP之神,源于以下两件事:
        1.曾用随机算法以1/(50^100)概率AC了一道dp题;
        2.省赛抽奖现场以1/600概率抽中特等奖获得一个4T的SSD。
    但大家不知道,LRC有一个测试当天RP值的奇葩方法。首先,用随机算法random出一个长度为n的数组a1,a2...,an;然后,再用随机算法random出一个长度为m的数组b1,b2...,bm;紧接着,依然是用随机算法random出一个正整数c;
接下来,LRC可以得到一个n*m的矩阵F,使得矩阵中的每个元素Fij=ai*bj;最后,计算一下F有多少个子矩阵,它的各个元素之和被c整除,那么这个值,就是他的RP值。
    现在LRC将所有的数random出来了,他想让未来校队的大神,也就是你,计算一下他的RP值。



输入格式

第一行一个正整数T(T<=20),代表测试数据的组数。
每组数据有3行。
第一行三个正整数n,m,c
第二行有n个正整数a1,a2...,an
第三行有m个正整数b1,b2...,bm
数据范围:
1<=n,m<=30000
1<=ai,bi<=30000
1<=c<=30000


输出格式

每组数据输出一行。
输出一个数,代表LRC的RP值。


输入样例

2
2 3 5
2 3
1 3 4
2 3 11
2 3
1 3 4



输出样例

6
0
2014-01-23 23:47
快速回复:呼叫版主,貌似是数学题
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.030639 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved