欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

hdu6052 To my boyfriend 2017多校2

程序员文章站 2024-03-15 15:33:30
...

http://acm.hdu.edu.cn/showproblem.php?pid=6052

我太菜了.jpg,比赛的时候没做出来

这种统计肯定是按数字来统计的,但我没想清楚怎么去重

其实只要考虑每个数字是多少个矩阵最上面一行最左边就行了

由于我们先优先最上面一行,所以下面肯定就随便算了,那么向下拓展的down始终为n-i+1

然后我们再从下向上枚举每一行有多少向左l和向右r,乘起来再乘以down就行了

首先在当前行他肯定是最左的一个,那么r=m-i+1,l就是到上一个+1的地方

然后枚举他上面的行,此时l,r都要更新了,因为我们考虑的是这个数字作为最上面一行的最左边的矩阵,不能让一个和他一样的数字出现在更上面的行。lower_bound搞搞就行了,复杂度是O(n*n*m*logn)的

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> p;

const int maxl=110;

int n,m;ll fz,fm;
int g[maxl][maxl];
struct node
{
	int x,y,num;
}b[maxl*maxl];
vector <int> a[maxl];

inline bool cmp(const node &a,const node &b)
{
	if(a.num==b.num)
	{
		if(a.x==b.x)
			return a.y<b.y;
		return a.x<b.x;
	}
	return a.num<b.num;
}

inline void prework()
{
	scanf("%d%d",&n,&m);
	int tot=0;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
		{
			scanf("%d",&g[i][j]);
			b[++tot]=node{i,j,g[i][j]};
		}
	sort(b+1,b+1+n*m,cmp);
}

inline void mainwork()
{
	int len,l,r,down,id,idx,len2,fir=1,now;fz=0;
	while(fir<=n*m)
	{
		for(int i=1;i<=n;i++) a[i].clear();
		now=fir;
		while(b[now].num==b[fir].num && now<=n*m)
			a[b[now].x].push_back(b[now].y),++now;
		fir=now;
		for(int i=1;i<=n;i++)
		{
			len=a[i].size();
			for(int j=0;j<len;j++)
			{
				id=a[i][j];
				l= (j==0) ? id:id-a[i][j-1];
				r= m-id+1;
				down=n-i+1;
				fz+=1ll*l*r*down;
				for(int di=i-1;di>=1;di--)
				{
					if((int)a[di].size()==0)
					{
						fz+=1ll*l*r*down;
						continue;
					}
					idx=lower_bound(a[di].begin(),a[di].end(),id)-a[di].begin();
					len2=a[di].size();
					if(idx<len2 && a[di][idx]==id)
						break;
					if(idx>0)
						l=min(l,id-a[di][idx-1]);
					if(idx<len2)
						r=min(r,a[di][idx]-id);
					fz+=1ll*l*r*down;
				}
			}
		}
	}
	fm=0;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			fm+=(n-i+1)*(m-j+1);
}

inline void print()
{
	double ans=1.0*fz/fm;
	printf("%.9f\n",ans);
}

int main()
{
	int t;
	scanf("%d",&t);
	for(int i=1;i<=t;i++)
	{
		prework();
		mainwork();
		print();
	}
	return 0;
}

 

相关标签: 计数