编程之美资格赛第二题--长方形

时间限制: 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


我的AC代码:
View Code
 1 #include <stdio.h>
 2 #include <math.h>
 3 
 4 int main()
 5 {
 6      int T,N,M,K;
 7      int i,j;
 8      int max;
 9      int result = 0;
10      int leaveK;
11      int num = 1;
12 
13      scanf("%d%*c",&T);
14 
15      while(num <= T)
16      {
17          scanf("%d %d %d%*c",&N, &M, &K);
18 
19          result = 0;
20          if(N > M)
21          {
22              i = M;
23              M = N;
24              N = i;
25          }
26 
27          i = int(sqrt(K * 1.0));
28          j = M;
29          i = i > N ? N : i;
30          for(; i * j > K; j--)
31              ;
32 
33          max = 0;
34          while(i >= 2 && j <= M)
35          {
36              leaveK = K;
37              result += (i * (i - 1) * j * (j - 1)) / 4;
38              leaveK -= i * j;
39              if(j < M)
40                  result += j * (leaveK * (leaveK - 1) / 2);
41              else
42                  result += i * (leaveK * (leaveK - 1) / 2);
43 
44              max = result > max ? result : max;
45 
46 
47              i--;
48              j = K / i;
49              result = 0;
50          }
51 
52          printf("Case #%d: %d\n", num++, max);
53      }
54      return 0;
55 }

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


posted @ 2013-04-07 14:10  3601  阅读(839)  评论(3编辑  收藏  举报