题意:
在 N 条水平线与 M 条竖直线构成的网格中,放 K 枚石子,每个石子都只能放在网格的交叉点上。问在最优的摆放方式下,
最多能找到多少四边平行于坐标轴的长方形,它的四个角上都恰好放着一枚石子。
思路:
这个题想了好多,还是没想明白。这就比较菜了...
这个题的话,先考虑什么情况下会使得得到的长方形最多.肯定是将其尽可能的填成x*y的形状的.即:x*y的格子中每一点都存在石子.从而可以得到C(x,2)*C(y,2)个长方形,.那么我们先考虑填成一个正方形,在继续补.k个石子最多可以填成kk=sqrt(k) ,kk*kk的正方形(超过就重复了),那么剩下的石子我们先考虑,将他补到长边上,这样新增加的和长边的又能构成很多的长方形,设剩余的为L ,即为C(L,2)*x(长边长).如果长边长超过了最大的限制,再补到短边上.
对于给定的k一定存在行列关系使得其最大,这里我们就枚举一个行的关系,固定行的大小小于列.并维护最优解
#include<bits/stdc++.h>
#define Ri(a) scanf("%d", &a)
#define Rl(a) scanf("%lld", &a)
#define Rf(a) scanf("%lf", &a)
#define Rs(a) scanf("%s", a)
#define Pi(a) printf("%d\n", (a))
#define Pf(a) printf("%lf\n", (a))
#define Pl(a) printf("%lld\n", (a))
#define Ps(a) printf("%s\n", (a))
#define W(a) while(a--)
#define CLR(a, b) memset(a, (b), sizeof(a))
#define MOD 1000000007
#define inf 0x3f3f3f3f
#define exp 0.00000001
#define pii pair<int, int>
#define mp make_pair
#define pb push_back
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
int n,m,k;
int t;
ll C(int s)
{
return s*(s-1)/2;
}
ll 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);
}
int main()
{
Ri(t);
int tt=1;
W(t)
{
Ri(n),Ri(m),Ri(k);
if(n>m)
swap(n,m);
int kk=sqrt(k);
int w=min(kk,n);
ll ans=0;
for(int i=2;i<=w;i++)
{
kk=min(m,k/i);
if(k>=kk*(i+1))//必须要保证多余石子少于边长
continue;
ll ss=solve(i,kk);
ans=max(ss,ans);
}
printf("Case #%d: ",tt++);
Pl(ans);
}
return 0;
}