题目描述
有n块木板,第i块木板的长度为a[i],现在把它们竖着拼在一起之后切割出一块正方形,求能得到的正方形的最大边长。
输入: 木板个数n,每一块木板的边长a[i]
输出: 正方形的最大边长
Sample 1
5
5 1 4 2 3
3
Sample 2
10
1 1 1 1 2 1 1 1 1 1
1
思路
将数组由大到小排序,则能切割出的最大正方形位于拼在一起后的图形的左下角,因此可以从左下角开始遍历数组,记录cur为横轴长度,当前的高度a[cur]为纵轴长度,nMaxLength为最大正方形的边长。如果纵轴的长度大于横轴的长度,说明当前遍历过的所有木板中存在一个长度为cur的正方形,此时更新nMaxLength;否则说明后面的所有木板无法再和前面的木板拼合出更大的正方形,跳出循环返回即可。
代码
#include <iostream>
#include <vector>
using namespace std;
void BubbleSort(vector<int>& a) {
for (int i = 0; i < a.size() - 1; ++i) {
for (int j = 0; j < a.size() - 1 - i; ++j) {
if (a[j] < a[j + 1]) {
int tmp = a[j];
a[j] = a[j + 1];
a[j + 1] = tmp;
}
}
}
return;
}
int LargestSquare(vector<int>& a) {
BubbleSort(a);
int nMaxLength = 1;
for (int cur = 1; cur < a.size(); ++cur) {
if (nMaxLength >= a[cur]) {
break;
}
else {
++nMaxLength;
}
}
return nMaxLength;
}
int main() {
int n;
cin >> n;
vector<int> a(n);
for (int i = 0; i < n; ++i) {
int ai;
cin >> ai;
a[i] = ai;
}
int result = LargestSquare(a);
cout << result << endl;
return 0;
}
坑
由于笔者头铁,非要从小到大排序之后从左到右遍历,各种分类讨论是否为连续上升之类,导致耗时过多还WA。希望大家引以为戒,牢记尽快AC高于一切,不要像笔者一样犯蠢
引申题目(以后再写)
如果题设允许将木板竖着拼接在其他木板上方?
如果题设允许将部分木板横着拼接?
如果要求输出一个最大矩形(而非正方形)的面积?
如果要求输出一个最大三角形的面积?(计算机图形学并感)