CodeForces-589B(思维/排序)
题目链接:http://codeforces.com/problemset/problem/589/B
题意:
有很多长方体蛋糕,高度默认为1,所以可以看作是矩形,你要做的是通过切割蛋糕来使得相同的蛋糕叠放起来达到最大的体积。你可以任意旋转长和宽。
思路:
首先既然可以任意旋转长和宽,那么不妨把输入的长和宽先按first < second的方式排好序,然后对整体排序,规则是优先first从小到大,其次考虑second从小到大。要求出最大的体积,肯定要遍历判断,更新最大值。这里有个技巧就是排好序后从后往前遍历,这样的话就保证了遍历过的蛋糕的first要比当前的大(保证遍历过的能切)。然后在每选定一个特定的first时对second进行遍历,所以要每次选定一个first时对能切的蛋糕的second排序再依次遍历second。(我感觉这个排序还是有点技巧的……
代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 const int maxn = 4010; 5 int n; 6 int two[maxn]; 7 pair<int, int>num[maxn]; 8 9 int main() 10 { 11 while(cin >> n) 12 { 13 long long sum = 0; 14 int w, h; 15 for(int i = 0; i < n; i++) 16 { 17 cin >> num[i].first >> num[i].second; 18 if(num[i].first > num[i].second) 19 { 20 int t = num[i].first; 21 num[i].first = num[i].second; 22 num[i].second = t; 23 } 24 } 25 sort(num, num + n); //优先第一个从小到大,选出first 26 int cnt = 0; 27 //下面这部分真的是理解了好久才看明白啊……哎 28 for(int i = n - 1; i >= 0; i--) //从后往前遍历,即保证了后面的都比前面的大(能切) 29 { 30 two[cnt++] = num[i].second; 31 sort(two, two + cnt); 32 for(int j = 0; j < cnt; j++) //长选中的是第i个,那么可以选择的宽就有cnt个,这里的目的就是遍历宽找最大面积 33 { 34 long long tmp = (long long)num[i].first * two[j] * (cnt - j); 35 if(tmp > sum) 36 { 37 sum = tmp; 38 w = num[i].first; 39 h = two[j]; 40 } 41 } 42 } 43 cout << sum << endl; 44 cout << w << " " << h << endl; 45 } 46 return 0; 47 }