您的位置:首页 > 其它

To my boyfriend HDU - 6052 多校第二场

2017-08-06 14:06 519 查看
参考:http://blog.csdn.net/calabash_boy/article/details/76272704

题意:题意:给出一个n*m(1<=n,m<=100)的矩阵,每个矩阵元素有一个颜色值ai(0<=ai<=10000),现在定义一个子矩阵的value为子矩阵中不同颜色的数量,求子矩阵value的期望。

所有矩阵可以用组合数求C(n,2)*C(m,2);

然后求每种颜色的贡献;

1

2 3

1 2 1

2 1 2

比如求颜色1时;

枚举1所在的所有位置;

(1,1):包含它的矩阵个数有6个,左边个数右边个数(上边界-下边界+1);

2*3*1=6;

(1,3):不能考虑(1,1) 2*1*2=4;

(2,2):因为不能考虑(1,1),(1,3);所以分两种情况,一种上边界为1,一种为2;

1*3*1+2*2*1=6;

同理枚举2所在位置

8+(3+2)+(2+2);

#include<bits/stdc++.h>
using namespace std;
const int MAX = 105;
int mp[MAX][MAX];
vector<pair <int,int> > Color[MAX*MAX];
pair <int,int> now;
int m,n;
void input(){
for (int i=0;i<=n*m;i++){
Color[i].clear();
}
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++){
for (int j = 1;j<=m;j++){
scanf("%d",&mp[i][j]);
Color[mp[i][j]].push_back(make_pair(i,j));
}
}
for (int i=0;i<=n*m;i++){
if (!Color[i].empty()){
sort(Color[i].begin(),Color[i].end());
}
}
}
vector<int> yIndex[MAX];
int bottom[MAX];
long long calc(int col)
{
//cout<<"Calcing "<<col<<endl;
memset(bottom,0,sizeof(bottom));
for (int i = 1;i<=n;i++){
yIndex[i].clear();
}
long long ans = 0;
for (int i=0;i<Color[col].size();i++){
now=Color[col][i];
int ni = now.first,nj = now.second;
//cout<<"Looping "<<ni<<","<<nj<<endl;
for (int i = 1;i<=m;i++){
yIndex[i].clear();
}
for (int i = 1;i<=m;i++){
if (bottom[i]){
yIndex[bottom[i]].push_back(i);
}
}
int yl=1,yr=m;
bool br = false;
for (int ii = ni;ii>=1;ii--){
//cout<<"Findind "<<ii<<endl;
for (vector<int>::iterator it = yIndex[ii].begin();it!=yIndex[ii].end();it++){
int yy = *it;
if (yy<nj){
yl = max(yl,yy+1);
}else if (yy>nj){
yr = min (yr,yy-1);
}else{
br = true;
break;
}
}
if (br){
break;
//cout<<"Finding Break"<<endl;
}
ans+=(n-ni+1)*(nj-yl+1)*(yr-nj+1);
//cout<<"Finding End:With"<<(n-ii+1)*(nj-yl+1)*(yr-nj+1)<<endl;
}
bottom[nj] = ni;
}

return ans;
}
double work(){
long long ans  = 0;
for (int i = 0;i<=n*m;i++){
if (!Color[i].empty()){
ans +=calc(i);
}
}
long long num = n*(n+1)*m*(m+1)/4;//多谢UFO___给我提出的改进建议
//  for (int i=1;i<=n;i++){
//      for (int j = 1;j<=m;j++){
//          num+=i*j;
//      }
//  }
double anss = ((double)ans)/num;
//  cout<<"ANS:"<<ans<<" NUM:"<<num<<" Return:"<<anss<<endl;
return anss;
}
int main(){
int Cas;
scanf("%d",&Cas);
while (Cas--){
input();
printf("%.9f\n",work());
}
return 0;
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: