题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5245
题意:给定一个n行m列的方阵,每次选2个点(x1,y1),(x2,y2),由这两个点为左上角和右下角可以确定一个矩形区域,将这个区域的格子涂黑;进行以上操作k次,问被涂黑的格子的数量的期望(四舍五入取整)。
分析 :
当K = 1时,期望染色面积是每一个方块染色的概率和;
假设K = 1时 位于 第 i 行,第 j 列 的染色概率为x( i , j );
则多次染色则的期望 P(i, j)
可用 P( i , j ) = 1 - (1 - x(i , j ))^k来表示;
然而x(i, j)怎么算呢?
我们先假设一个5行5列的方阵
可以把矩阵按如下拆分
对于整个方阵,取一个点的种类共有m*n种,
所以取两个点则有m*n*m*n种;
计算方块5的被染色的概率x(i, j),根据点1 (x1 , y1)的位置 , 可以确定种类数。
•若(x1,y1)在区域1,则(x2,y2)必然在区域5,6,7,8,种数
(i-1)*(j-1)*(m-i+1)*(n-j+1);
•若(x1,y1)在区域2,则(x2,y2)必然在区域4,5,6,7,8,9,种数 (i - 1)*(m - i +1)*n;
•若(x1,y1)在区域3,则(x2,y2)必然在区域4,5,7,8,种数
(i - 1)*(n - j)*j*(m - i + 1);
•若(x1,y1)在区域4,则(x2,y2)必然在区域2,3,5,6,8,9,种数
(j - 1)*m*(n - j + 1);
•若(x1,y1)在区域5,则(x2,y2)必然在区域1,2,3,4,5,6,7,8,9,种数 n * m ;
•若(x1,y1)在区域6,则(x2,y2)必然在区域1,2,4,5,7,8,种数 (n - j)*m*j;
•若(x1,y1)在区域7,则(x2,y2)必然在区域2,3,5,6,种数
(m - i)*(j - 1)*i*(n - j + 1);
•若(x1,y1)在区域8,则(x2,y2)必然在区域1,2,3,4,5,6.种数 (m - i)*i * n;
•若(x1,y1)在区域9,则(x2,y2)必然在区域1,2,4,5,种数
(m - i)*(n - j)*i*j;
将种类数相加就是x(i, j);
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
int main()
{
int T,k,Case = 1;
scanf("%d",&T);
while(T--)
{
double p = 0,x,n,m;
scanf("%lf %lf %d",&m,&n,&k);
for(int i = 1 ; i <= m ; i ++ )
{
for(int j = 1 ; j <= n ; j ++ )
{
x = 0;
x += (i - 1)*(j - 1)*(m - i + 1)*(n - j +1);
x += (i - 1)*(m - i +1)*n;
x += (i - 1)*(n - j)*j*(m - i + 1);
x += (j - 1)*m*(n - j + 1);
x += n * m;
x += (n - j)*m*j;
x += (m - i)*(j - 1)*i*(n - j + 1);
x += (m - i)*i * n;
x += (m - i)*(n - j)*i*j;
x = x/(n * n * m * m);
p += 1-pow(1 - x , k);
}
}
printf("Case #%d: %.0lf\n",Case++ , p);
}
return 0;
}