标签:
Description
Input
Output
Sample Input
Sample Output
Hint The precise answer in the first test case is about 3.56790123.
题意:有t组数据,每组输入m,n,k。表示有一个m*n的矩阵,在矩阵中随机取两个点(x1,y1),(x2,y2),以这两个点为矩形的
两个顶点,画一个矩形,即矩形的四个顶点为(x1,y1),(x1,y2),(x2,y1),(x2,y2)。矩形中的所有点视为被染色,进行k
次这样的操作,问该矩阵中被染色的格子的个数的期望。这两个点互不影响,也就是这两个点可以相同。每个点可以被多次染
色,就是被染两次就算两次,不是算一次。
题解:因为(x1,y1),(x2,y2)这两个点是从矩阵中取的,第一个点有n*m种可能性,第二个点也有n*m种可能性,所以总的情况
数为n*n*m*m。我们对矩阵中的每个点进行单独讨论,假设有这么一个点x,y。我们知道,x表示该点在第x行,y表示该
点在第y列,那么如果取的那两个点(x1,y1),(x2,y2)都在1到x-1行或者都在x+1到m行之间或者都在1到y-1列之间或者
都在y+1到n列之间,则(x,y)这个点不会被染色,将上面的四种情况可以看做是上下左右四种情况。根据容斥原理,我们要
减去左上,左下,右上,右下这四种情况,这是因为上和左同时覆盖左上,以此类推。用该情况数除以总情况数所得概率p就
是该点不被染色的概率,进行k次该操作,则tmp=p^k就是该点k次操作之后不被染色的概率,1-tmp就是该点被染色的概率,
因为该点是一个点,所以概率就是期望,将每个点的期望加起来,就是结果了,注意四舍五入用%.0f就能实现,具体的有很多
很多需要注意的细节问题请看代码注释。
#include <iostream> #include <stdio.h> #include <math.h> using namespace std; typedef long long ll; ll c(ll a,ll b) { return a*a*b*b; } int main() { /*1.用G++提交 用C++慢 2.用scanf写 用cin慢 虽然在本题中一样 3.求k次概率的tmp用循环跑 用pow慢*/ ll t,n,m,k;//注意这里一定要用long long,要不然计算的时候还得强制转化一下 ll ans,sum; double p,tmp,qiwang; scanf("%lld",&t); for(int cas=1;cas<=t;cas++) { scanf("%lld%lld%lld",&n,&m,&k);//这里n和m的顺序无所谓 qiwang=0;//qiwang表示该格子被染色的概率也就是期望,因为n是1 p=0;//p表示该格子一次操作后不被染色的概率 tmp=1;//tmp表示该格子k次操作后不被染色的概率 sum=n*n*m*m;//除以sum求概率用 //注意下面的代码n和m是反的 但是对答案没有任何影响 for(int i=1;i<=n;i++)//对每个格子进行讨论 for(int j=1;j<=m;j++) { ans=0;//初始化 ans+=c(i-1,m); ans+=c(n-i,m); ans+=c(j-1,n); ans+=c(m-j,n); ans-=c(i-1,j-1); ans-=c(i-1,m-j); ans-=c(j-1,n-i); ans-=c(n-i,m-j);//容斥原理 p=1.0*ans/sum;//该格子不被染色的概率 tmp=1.0;//初始化 for(int x=1;x<=k;x++)//比pow好 tmp*=p;//该格子k次之后还不被染色的概率 qiwang=qiwang+1-tmp;//该格子被染色的概率即期望 } printf("Case #%d: %.0f\n",cas,qiwang);// %0.f自动取整了 floor或者+0.5或者round函数也可以 } return 0; }
标签:
原文地址:http://www.cnblogs.com/Ritchie/p/5449741.html