To my boyfriend

To my boyfriend

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 969    Accepted Submission(s): 446


Problem Description
Dear Liao

I never forget the moment I met with you. You carefully asked me: "I have a very difficult problem. Can you teach me?". I replied with a smile, "of course". You replied:"Given a matrix, I randomly choose a sub-matrix, what is the expectation of the number of **different numbers** it contains?"

Sincerely yours,
Guo
 

Input
The first line of input contains an integer T(T≤8) indicating the number of test cases.
Each case contains two integers, n and m (1≤n, m≤100), the number of rows and the number of columns in the grid, respectively.
The next n lines each contain m integers. In particular, the j-th integer in the i-th of these rows contains g_i,j (0≤ g_i,j < n*m).
 

Output
Each case outputs a number that holds 9 decimal places.
 

Sample Input
  
  
1 2 3 1 2 1 2 1 2
 

Sample Output
  
  
1.666666667
 
   
   
Hint
6(size = 1) + 14(size = 2) + 4(size = 3) + 4(size = 4) + 2(size = 6) = 30 / 18 = 6(size = 1) + 7(size = 2) + 2(size = 3) + 2(size = 4) + 1(size = 6)
 

题意:

     给出一个n*m的矩阵,每个1*1的小矩阵中都有一个数字,现在求大矩阵中所有的矩阵所包含的数字种类和,再除以所有的矩阵数,求数字的期望。

思路:

    我们假设一个数字代表一种颜色,便于下面描述。 

   首先介绍一种求大矩阵中所有矩阵个数的方法。

    一个n*m的矩阵,它所包含的所有矩阵个数为:

int total=0;
for (int i=1; i<=n; i++)
    for (int j=1; j<=m; j++)
        total=total+i*j;

     此公式代表,以(i,j)这个小矩阵块为右下角的矩阵共有多少个,即从前i行中找一行作为大矩阵的上边,从前j列中找一列作为大矩阵的左列,这样所形成的大矩阵有多少种,即C(i,1)*C(j,1)即i*j。遍历矩阵的每一个1*1小矩阵,就可得n*m的矩阵总个数。

     下面介绍如何求出大矩阵中所有的矩阵所包含的颜色种类和。我们以一种颜色为例,这种颜色对答案的贡献为,所有包含这种颜色的矩形个数。我们遍历这种颜色的每一个1*1小矩阵,找出包含这个小矩阵的所有矩阵,就可以得出这个小矩阵对答案的贡献,再遍历所有该颜色的小矩阵,相加就可以得出该颜色对答案的贡献。但是这样直接算会产生重复。所以我们探讨消除这种重复的方法。

     首先,我们遍历时找的是,有多少个矩阵包含这个小矩阵,也就是说,有多少个矩阵至少包含一种这样的颜色,现在我们只要保证每次遍历都不与之前的重复,我们就可以消除重复。所以我们定义一种模式,即遍历每一个1*1小矩阵时,我们只能包含这个小矩阵以下,以右的同颜色矩阵,而这个小矩阵以左,以上的同颜色矩阵不再包含,这样就可以实现每次计算时都不重复。这样我们就转化成为寻找边界,即为寻找遍历该小矩阵时,我们所能计算的矩阵的边界。我们在之前定义的方法的限制下,找到每一个小矩阵所形成的上边界,下边界,左边界,有边界,其中这四条边界每一条都是不固定的。其中,由于上边界和下边界的取值范围固定,(设该小矩阵的位置是(x,y),则上边界的取值范围是1x,下边界的取值范围是xn),所以我们主要是通过枚举上边界,去限制左右边界。如何找边界及找到边界如何计算详见代码注释。

下面贴上代码:(具体实现过程详见注释)

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
const int MAXN=105;

int n, m;
int color[MAXN][MAXN];

int count(int x, int y)
{
    LL ans=0;
    int c=color[x][y]; //c是颜色号

    int L=1,R=m; //左边界初始化为1,右边界为m
    for (int i=x; i>=1; i--) //把每一次上边界确定为i,根据上边界限制左右边界
    {
        if (i<x && color[i][y]==c)
            break;
//遍历到第i行,若i<x && color[i][y]==c则说明[x][y]的正上方有一个同颜色的矩阵
//此时无论我们怎样确定左右边界,由于下边界为x到n,我们所得出的矩阵都一定会包含[i][y]这个矩阵
//而根据记下记右,不记上不记左的原则,我们不应包含[i][y]这个小矩阵,所以直接break

        int l=y,r=y; //左右边界均从当前列的位置左右移动
        for (int j=y-1; j>=max(1,L); j--)
        {
            if (color[i][j]==c) //从当前列数向左找,找到i行第一个同颜色的方块,记录下左边界
                break;
            l=j;
        }
        L=max(L,l);

        if (i==x) //如果i为当前行,(即上边界为x),则只需要找左边界,右边界为m(因为可以包括右边和下边的相同颜色方块)
        {
            ans=ans+(LL)(n-x+1LL)*(y-L+1LL)*(R-y+1LL);
            continue;
        }

        for (int j=y+1; j<=min(m,R); j++)
        {
            if (color[i][j]==c) //从当前列数向右找,找到i行第一个同颜色的方块,记录下右边界
                break;
            r=j;
        }
        R=min(R,r);

        ans=ans+(LL)(n-x+1LL)*(y-L+1LL)*(R-y+1LL);
//这个公式代表,从x到n中选取一行作为所选矩形的下边,所选矩形的上边为第i行
//从L到y中选一列作为所选矩形的左边,从y到R中选一列作为矩形的右边
//四条线所圈出的矩形就是所选矩形
    }
    return ans;
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        for (int i=1; i<=n; i++)
            for (int j=1; j<=m; j++)
                scanf("%d",&color[i][j]);

        LL ask=0,total=0;
        for (int i=1; i<=n; i++)
        {
            for (int j=1; j<=m; j++)
            {
                ask=ask+count(i,j);
                total=total+i*j; //计算n*m矩阵有多少个小矩阵,简单算法
            }
        }
        printf("%.9f\n",ask*1.0/total);
    }
    return 0;
}


weixin073智慧旅游平台开发微信小程序+ssm后端毕业源码案例设计 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
python017基于Python贫困生资助管理系统带vue前后端分离毕业源码案例设计 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
weixin102旅游社交微信小程序+ssm后端毕业源码案例设计 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值