2013编程之美资格赛【长方形】

时间限制: 1000ms 内存限制: 256MB


描述
在 N 条水平线与 M 条竖直线构成的网格中,放 K 枚石子,每个石子都只能放在网格的交叉点上。问在最优的摆放方式下,最多能找到多少四边平行于坐标轴的长方形,它的四个角上都恰好放着一枚石子。


输入
输入文件包含多组测试数据。


第一行,给出一个整数T,为数据组数。接下来依次给出每组测试数据。


每组数据为三个用空格隔开的整数 N,M,K。


输出
对于每组测试数据,输出一行"Case #X: Y",其中X表示测试数据编号,Y表示最多能找到的符合条件的长方形数量。所有数据按读入顺序从1开始编号。


数据范围
1 ≤ T ≤ 100


0 ≤ K ≤ N * M


小数据:0 < N, M ≤ 30


大数据:0 < N, M ≤ 30000






样例输入
3
3 3 8
4 5 13
7 14 86
样例输出
Case #1: 5
Case #2: 18
Case #3: 1398



#include <iostream>
#include <stdio.h>
#include <cstring>
#include <vector>
#include <map>
#include <algorithm>
#include <math.h>
#include <fstream>
using namespace std;
typedef long long LL;
int main()
{
        int T,x;
        while(scanf("%d",&T)==1)
        {
                for(x=1;x<=T;x++)
                {
                        LL N,M,K;
                        scanf("%lld%lld%lld",&N,&M,&K);
                        if(N>M)//让M大于N
                        {
                                N=M+N;
                                M=N-M;
                                N=N-M;
                        }
                        int n=sqrt(K)>N?N:sqrt(K);
                        int m=M;
                        while(n * m>K)
                                m--;
                        LL ans=0;
                        LL res=0;
                        while(n>=2&&m<=M)
                        {
                                LL k=K;
                                res += (n*m*(n-1)*(m-1))>>2 ;
                                k -= m*n;
                                if(m < M)
                                        res+=(m*k*(k-1))>>1;
                                else
                                        res+=(n*k*(k-1))>>1;
                                ans=res>ans?res:ans;
                                res=0;
                                n --;
                                m=K/n;
                        }
                        printf("Case #%d: %lld\n",x,ans);
                }
        }
        return 0;
}


需要用到组合数学,还是破费了一番周折。思路就是先找到在网格中最大能形成的长方形矩阵的长x和宽y,算出剩余石子l,根据公式xy(x-1)(y-1)/4算出最大长方形矩阵可形成的长方形数量(正方形也属于长方形),再算出最长边加入剩余石子后可形成的长方形数量x * (l * (l-1)/2),他们的和即为结果。


你可能感兴趣的:(2013编程之美资格赛【长方形】)