HHKB Programming Contest 2020 D

题目链接

题目描述

在二维平面给定一个长度为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;
}

原文地址:https://www.cnblogs.com/ZX-GO/p/13801723.html