【推理】单元格(jzoj 1509)

版权声明:欢迎借鉴,谢绝抄搬。 https://blog.csdn.net/ssllyf/article/details/86695131

单元格

题目大意:

在一个R×C的矩形中选三个点,使他们行列各不同,定义“费用”为,这三个点之间的行列的差值的和(1,2和3,4费用是差值是(3-1)+(4-2)=2+2=4),问差值不小于minT,不大于maxT的三个点中,选定的三个点不同的方案有多少种(结果对1000000007取模)

数据范围限制

3≤R,C≤4000, 1≤minT≤maxT≤20000

提示

在这里插入图片描述

解题思路:

我们先定一个长为4(i),宽为4(j)的矩形(如下图),这三个点可以在它的边界上定义,我们先固定一个点(黑点),然后另外两个点可以在另外两条边上定义(不能在交点上),这种情况的种数是(i-2)×(j-2),因为矩形有四个点,所以乘上4:4×(i-2)×(j-2)

在这里插入图片描述

然后我们可以固定两个对顶点(如图),然后另外一个点可以在中间定义,种数为(i-2)×(j-2),因为对顶点有两对所以有2×(i-2)×(j-2)种可能

在这里插入图片描述

合并前面两种,则为6×(i-2)×(j-2),然后这种矩形在全图的个数可以从下图看出(不要问我为什么用绿色,因为我左边的CNH奆佬喜欢绿色),他的个数是四个(行有两个三,列有两个三,相乘为4),则为(R-i+1)×(C-j+1),总结一下就是6×(i-2)×(j-2)×(R-i+1)×(C-j+1),然后直接枚举i和j就行了

在这里插入图片描述

#include<cstdio>
#include<iostream>
using namespace std;
long long n,m,maxx,minn,ans;
int main()
{
	scanf("%lld %lld %lld %lld",&n,&m,&minn,&maxx);
	for (long long i=3;i<=n;++i)//枚举i
	  for (long long j=3;j<=m;++j)//枚举j
	    if ((i+j-2)*2<=maxx&&(i+j-2)*2>=minn)//判断是否符合题意
	      ans=(ans+6*(i-2)*(j-2)*(n-i+1)*(m-j+1))%1000000007;//代入公式,取模
	printf("%lld",ans);//输出结果
	return 0;
}

猜你喜欢

转载自blog.csdn.net/ssllyf/article/details/86695131