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
InputThe 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).OutputEach 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列的二维数组,数组中的每一个数值表示颜色。问二维数组构成的矩形中有不同的颜色和除以二维数组构成的不同矩形数 解题思路:首先要算出一个颜色的不同上下左右边界,假定下边界固定了。然后求出上边界,如果上边界的相同位置和本身的颜色相同就结束这个搜索,当i==x是只要求出左边界就行了。最后求出左边界和右边界算出矩阵的个数即可。枚举二维数组中中每一颜色加和就能得到二维数组构成的矩形中有不同的颜色和。
二维数组构成的不同矩形数=n*(n+1)*m*(m+1)/4
AC代码:
1 #include <iostream> 2 #include <bits/stdc++.h> 3 #define LL long long 4 using namespace std; 5 int n,m; 6 LL color[105][105]; 7 LL count(int x,int y) 8 { 9 LL res=0; 10 int L=1,R=m,c=color[x][y]; 11 for(int i=x;i>=1;i--) 12 { 13 if(i<x&&c==color[i][y]) break; 14 int l=y,r=y; 15 for(int j=y-1;j>=max(1,L);j--) 16 { 17 if(c==color[i][j]) break; 18 l=j; 19 } 20 L=max(L,l); 21 if(i==x) 22 { 23 res+=(LL)(n-x+1LL)*(y-L+1LL)*(R-y+1LL); 24 continue; 25 } 26 for(int j=y+1;j<=min(R,m);j++) 27 { 28 if(c==color[i][j]) break; 29 r=j; 30 } 31 R=min(R,r); 32 res+=(LL)(n-x+1LL)*(y-L+1LL)*(R-y+1LL); 33 } 34 return res; 35 } 36 int main() 37 { 38 int t; 39 while(~scanf("%d",&t)) 40 { 41 while(t--) 42 { 43 scanf("%d%d",&n,&m); 44 LL ss=n*(n+1)/2*m*(m+1)/2; 45 for(int i=1;i<=n;i++) 46 { 47 for(int j=1;j<=m;j++) 48 { 49 scanf("%lld",&color[i][j]); 50 } 51 } 52 LL ans=0; 53 for(int i=1;i<=n;i++) 54 { 55 for(int j=1;j<=m;j++) 56 { 57 //printf("%lld\n",count(i,j)); 58 ans+=count(i,j); 59 } 60 } 61 //printf("%lld %lld\n",ans,ss); 62 printf("%.9f\n",ans*1.0/ss); 63 } 64 } 65 return 0; 66 }