长方形

题目大意

N N N 条水平线与 M M M 条竖直线构成的网格中,放 K K K 枚石子,每个石子都只能放在网格的交叉点上。

问在最优的摆放方式下,最多能找到多少四边平行于坐标轴的长方形,它的四个角上都恰好放着一枚石子。

解题思路

显然,最优的摆放方式是所有的石子都聚集在一起。

所以摆放方式可以表示为一个长方形加上多出的几个石子。

设长方形的长为 x x x,宽为 y y y,则多出的石子个数为 k − x ∗ y k-x*y kxy,暂且记为 z z z

那么此时构成的长方形个数分为两种情况:

  • y ≤ m y \leq m ym C x 2 × C y 2 + y ∗ C z 2 C_{x}^{2} \times C_{y}^{2} + y*C_{z}^{2} Cx2×Cy2+yCz2
  • y = m y=m y=m C x 2 × C y 2 + x ∗ C z 2 C_{x}^{2} \times C_{y}^{2} + x*C_{z}^{2} Cx2×Cy2+xCz2

式子应该很好推的。

AC CODE

#include <bits/stdc++.h>

using namespace std;

int read()
{
    int x = 0;
    char c = getchar();
    while (c < '0' || c > '9')
        c = getchar();
    while (c >= '0' && c <= '9')
    {
        x = x * 10 + c - '0';
        c = getchar();
    }
    return x;
}

int n, m, k;

long long ans;

long long C(int x)
{
    return (x - 1) * x / 2;
}

long long solve(int x, int y)
{
    if (y < m)
    {
        return C(x) * C(y) + y * C(k - x * y);
    }
    else
    {
        return C(x) * C(y) + x * C(k - x * y);
    }
}

signed main()
{
    n = read(), m = read(), k = read();
    if (n > m)
        swap(n, m);
    for (int i = 2, r = min(n, (int)sqrt(k)); i <= r; ++i)
    {
        // cout << i << endl;
        int x = min(m, k / i);
        if (k >= x * (i + 1))
            continue;
        ans = max(ans, solve(i, x));
    }
    printf("%lld\n", ans);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值