题目描述
在二维平面给定一个长度为n的正方形大小区域,需要将边长为a,b的正方形不相交的放入这个区域,求所有的方案数。
思路
如果两个正方形相交,即可发现其投影在x轴和y轴上的边全部重合,因此就是求边长为a,b的线段在长度为n的线段上不重合的所有摆法的方案数。而且只要这个投影在x轴上不重合或者在y轴上不重合即可。
边长为a的边左端点放在0位置上,那么b线段左端点能放的位置就是([a, n - b])上的任意一点,方案数即为(n-a-b+1)。
同理可推出边界情况就是将线段a放在n-b-a这个位置上,b只能放在n-b这个位置上,方案数为1种。
设(d = n - b - a),那么所有的方案数就是(sum_{x = 1}^{d+1}x),即为((d+2)*(d+1)/2).因为可以考虑a在b左边或者是a在b右边,就有2种方案。所以仅考虑x轴不相交的情况或者y轴不相交的情况时的方案数为(ans1 = (d+1)*(d+2)*(n-a-1)*(n-b-1))。
x轴不相交y轴也不相交的情况即为(ans2 = (d+1)^2*(d+2)^2).
所以答案就是(2*an1-ans2),因为x轴y轴都不相交的计算次数多计算了一次。
注意考虑特判0的情况。
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int mod = 1e9 + 7;
void solve() {
LL n, a, b;
scanf("%lld%lld%lld", &n, &a, &b);
if(n < a + b) {
puts("0");
return;
}
LL d = n - a - b;
LL x = d + 1, y = d + 2;
LL res = 2 * x % mod * y % mod * (n - a + 1) % mod * (n - b + 1) % mod; res %= mod;
res -= x * x % mod * y % mod * y % mod; res = (res + mod) % mod;
printf("%lld
", res);
}
int main() {
// freopen("in.txt", "r", stdin);
int t; scanf("%d", &t); while(t--)
solve();
return 0;
}