您的位置:首页 > 其它

HDU 6052 To my boyfriend 思维 + 枚举(计数)

2017-07-28 23:04 441 查看
传送门:HDU6052

题意:给出一个n*m的矩阵,每个点有一种颜色,定义矩阵的val为矩阵中不同颜色的数量,问任意一个子矩阵的val的期望为多少。

思路:我是直接看了一篇讲解的想不理解都难的博客:点击打开链接

代码:

#include<bits/stdc++.h>
#define ll long long
#define pb push_back
#define fi first
#define se second
#define pi acos(-1)
#define inf 0x3f3f3f3f
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define rep(i,x,n) for(int i=x;i<n;i++)
#define per(i,n,x) for(int i=n;i>=x;i--)
using namespace std;
typedef pair<int,int>P;
const int MAXN=10010;
int gcd(int a,int b){return b?gcd(b,a%b):a;}
int n, m;
vector<P> color[MAXN];
vector<int> Y[110];
int last[110];
ll calc(int col)
{
ll ans = 0;
memset(last, 0, sizeof(last));
for(int o = 0; o < color[col].size(); o++)
{
int tx = color[col][o].fi, ty = color[col][o].se;
for(int i = 1; i <= m; i++)
Y[i].clear();
for(int i = 1; i <= m; i++)
if(last[i])
Y[last[i]].pb(i);
int tl = 1, tr = m;
bool flag = 0;
for(int i = tx; i >= 1; i--)
{
for(int j = 0; j < Y[i].size(); j++)
{
int tmp = Y[i][j];
if(tmp < ty)
tl = max(tl, tmp + 1);
else if(tmp > ty)
tr = min(tr, tmp - 1);
else
{
flag = 1;
break;
}
}
if(flag) break;
ans += 1ll * (n - tx + 1) * (ty - tl + 1) * (tr - ty + 1);
}
last[ty] = tx;
}
return ans;
}
int main()
{
int T, c;
scanf("%d", &T);
while(T--)
{
scanf("%d %d", &n, &m);
for(int i = 0; i <= n * m; i++)
color[i].clear();
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
scanf("%d", &c), color[c].pb(P(i, j));
for(int i = 0; i <= n * m; i++)
if(color[i].size())
sort(color[i].begin(), color[i].end());
ll sum = 0, ans = 0;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
sum += 1ll * i * j;
for(int i = 0; i <= n * m; i++)
if(color[i].size())
ans += calc(i);
printf("%.9lf\n", (double)ans * 1.0 / sum);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: