在 N 条水平线与 M 条竖直线构成的网格中,放 K 枚石子
【題目描述】
在 N 條水平線與 M 條豎直線構(gòu)成的網(wǎng)格中,放 K 枚石子,每個石子都只能放在網(wǎng)格的交叉點上。問在最優(yōu)的擺放方式下,最多能找到多少四邊平行于坐標軸的長方形,它的四個角上都恰好放著一枚石子。
【輸入】
輸入文件包含多組測試數(shù)據(jù)。
第一行,給出一個整數(shù)T,為數(shù)據(jù)組數(shù)。接下來依次給出每組測試數(shù)據(jù)。
每組數(shù)據(jù)為三個用空格隔開的整數(shù) N,M,K。
【輸出】
對于每組測試數(shù)據(jù),輸出一行"Case #X: Y",其中X表示測試數(shù)據(jù)編號,Y表示最多能找到的符合條件的長方形數(shù)量。所有數(shù)據(jù)按讀入順序從1開始編號。
?
【題解】
??? 首先先考慮對于一個布滿點的矩形(x行,Y列),所有的矩形總數(shù)為 C(2,x)*C(2,y)。要使數(shù)量最多,則x和y要盡可能接近(有最大行和最大列的限制)。??? 題中所給的K可能不能剛好排成大矩形,可能有多余的幾個點,這幾個點的數(shù)量一定不會超過一行或一列的最大數(shù)量。 試想如果超過,則多出來完整的一行或一列可以和原來的大矩形構(gòu)成更大的矩形,剩下的點就不能構(gòu)成完整的一行或一列了。
????多余多出來的點,以一排或一列的形式,靠在大矩形短的一邊(要注意是否到達邊界),設(shè)多余K個點,則多增加的矩形數(shù)為 C(2,K)*L (L為長邊的點數(shù))。
??? 為了簡單起見,可以規(guī)定行大于列(對調(diào)旋轉(zhuǎn)下),枚舉 X、Y的有效極大組合,找出最大的結(jié)果就行了。
??? AC代碼:
1 #include <stdio.h> 2 #include <string.h> 3 #include <math.h> 4 int n,m,k; 5 void swap(int &a,int &b) 6 { 7 int t=a; 8 a=b; 9 b=t; 10 } 11 long long getc(long long j) 12 { 13 return j*(j-1)/2; 14 } 15 int main() 16 { 17 int T; 18 scanf("%d",&T); 19 int cas=0; 20 while (T--) 21 { 22 scanf("%d%d%d",&n,&m,&k); 23 if (n<m) swap(n,m); 24 int t=sqrt(k); 25 int b=t>m?m:t; 26 int a=k/b>n?n:k/b; 27 long long max=0; 28 for (;b>=2 && a<=n;--b,a=k/b) 29 { 30 long long sum=getc(a)*getc(b); 31 int p=k-a*b; 32 if (a<n) 33 { 34 sum=sum+getc(p)*a; 35 } 36 else 37 { 38 sum=sum+getc(p)*b; 39 } 40 max=max>sum?max:sum; 41 } 42 printf("Case #%d: %I64d\n",++cas,max); 43 } 44 45 return 0; 46 }總結(jié)
以上是生活随笔為你收集整理的在 N 条水平线与 M 条竖直线构成的网格中,放 K 枚石子的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。