微软编程之美 Qual_B:长方形 思维

来源:互联网 发布:鑫园合成软件 编辑:程序博客网 时间:2024/05/16 13:46

题目链接



题意:

在 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_backusing 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);elsereturn 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;}

原创粉丝点击