POJ 1169解题报告
2012-12-03 11:05
274 查看
这道题也是usaco上的题,所以有测试数据,帮着调试了两个bug。
题中已经给出了所有的6种情况(4和5是一样的),所以按照这六种情况尝试就好了。
对每种情况,矩形有不同的排列。比如case1是1种,case2是4种,case3是C_4^2,case4case5是c_4^2,case6是全排列。
矩形本身有可以旋转,所以四个矩形关于旋转与否有2^4=16种状态。
然后就是罗列上述情况,记录最小面积(及对应的宽)就可以了。
题中已经给出了所有的6种情况(4和5是一样的),所以按照这六种情况尝试就好了。
对每种情况,矩形有不同的排列。比如case1是1种,case2是4种,case3是C_4^2,case4case5是c_4^2,case6是全排列。
矩形本身有可以旋转,所以四个矩形关于旋转与否有2^4=16种状态。
然后就是罗列上述情况,记录最小面积(及对应的宽)就可以了。
#include <cstdio> #include <cstdlib> #include <iostream> #include <vector> #include <algorithm> #include <cassert> using namespace std; void check(int wid, int hig, int &minarea, vector<pair<int, int> > &sols) { int area = wid * hig; if(area < minarea) { minarea = area; sols.clear(); sols.push_back(make_pair<int, int>(wid, hig)); } else if(area == minarea) { sols.push_back(make_pair<int, int>(wid, hig)); } } int main() { //FILE *fin, *fout; //fin = fopen("packrec.in", "r"); //fout = fopen("packrec.out", "w"); //assert(fin != NULL && fout != NULL); int sqs_in[4][2]; for(int i = 0; i < 4; ++i) { for(int j = 0; j < 2; ++j) { //fscanf(fin, "%d", &sqs_in[i][j]); fscanf(stdin, "%d", &sqs_in[i][j]); } } int minarea = 50 * 4 * 50 * 4; vector<pair<int, int> > sols; int sqs[4][2]; for(int per = 0; per < 16; ++per) { int tmp = per; for(int bit = 0; bit < 4; ++bit) { if(tmp % 2 == 0) { sqs[bit][0] = sqs_in[bit][0]; sqs[bit][1] = sqs_in[bit][1]; } else { sqs[bit][0] = sqs_in[bit][1]; sqs[bit][1] = sqs_in[bit][0]; } tmp >>= 1; } int sumw = 0; for(int i = 0; i < 4; ++i) sumw += sqs[i][0]; //case 1 int wid = sumw; int hig = sqs[0][1]; for(int i = 1; i < 4; ++i) { if(sqs[i][1] > hig) hig = sqs[i][1]; } check(wid, hig, minarea, sols); //case 2 for(int i = 0; i < 4; ++i) { wid = sumw - sqs[i][0]; wid = max(wid, sqs[i][1]); hig = -1; for(int j = 0; j < 4; ++j) { if(j != i && sqs[j][1] > hig) hig = sqs[j][1]; } hig += sqs[i][0]; check(wid, hig, minarea, sols); } //case 3 for(int i = 0; i < 4; ++i) { for(int j = i + 1; j < 4; ++j) { for(int k = 0; k < 2; ++k) { int l = (k == 0? i : j); int r = (k == 0? j : i); wid = max(sqs[l][1] + sqs[r][0], sumw - sqs[l][0]); hig = sqs[r][1]; for(int t = 0; t < 4; ++t) { if(t != l && t != r && sqs[l][0] + sqs[t][1] > hig) { hig = sqs[l][0] + sqs[t][1]; } } check(wid, hig, minarea, sols); } } } //case 4 && case 5 for(int i = 0; i < 4; ++i) { for(int j = i + 1; j < 4; ++j) { wid = sumw - min(sqs[i][0], sqs[j][0]); hig = sqs[i][1] + sqs[j][1]; for(int k = 0; k < 4; ++k) { if(k != i && k != j && sqs[k][1] > hig) hig = sqs[k][1]; } check(wid, hig, minarea, sols); } } //case 6 int arr[4] = {0, 1, 2, 3}; do { wid = max(sqs[arr[0]][0] + max(sqs[arr[3]][0], sqs[arr[1]][1]), sqs[arr[2]][0] + sqs[arr[3]][0]); hig = max(sqs[arr[0]][1] + sqs[arr[2]][1], sqs[arr[1]][0] + max(sqs[arr[2]][1], sqs[arr[3]][1])); check(wid, hig, minarea, sols); }while(next_permutation(arr, arr + 4)); } //fprintf(fout, "%d\n", minarea); fprintf(stdout, "%d\n", minarea); vector<int> wids; for(int i = 0; i < sols.size(); ++i) { wids.push_back(min(sols[i].first, sols[i].second)); } sort(wids.begin(),wids.end()); //fprintf(fout, "%d %d\n", wids[0], minarea / wids[0]); fprintf(stdout, "%d %d\n", wids[0], minarea / wids[0]); for(int i = 1; i < wids.size(); ++i) { if(wids[i] != wids[i - 1]) { fprintf(stdout, "%d %d\n", wids[i], minarea / wids[i]); } } return 0; }
相关文章推荐
- poj 2406 Power Strings(字符问题)(解题报告)
- POJ1247解题报告——我写的第一篇解题报告
- poj解题报告——2425
- poj(百练) 2975 解题报告
- POJ 1273 解题报告
- POJ - 3176 Cow Bowling解题报告(求三角形数最大路)
- poj2502解题报告(Dijskstra算法)
- POJ-1274-The Perfect Stall 解题报告
- [解题报告]POJ2352 Stars 树状数组
- poj 2342 Anniversary party 树形DP 解题报告
- poj解题报告——1704
- 解题报告 之 POJ1087 A Plug for UNIX
- POJ 3264 解题报告
- ACM PKU POJ 1112 解题报告
- poj解题报告——3480
- 解题报告——POJ 2299
- POJ 1503 Integer Inquiry 解题报告
- 单调队列 - 兼 ACM PKU POJ 3250 及 2823 解题报告 [转]
- POJ 1811 解题报告
- poj 3617 Best Cow Line 解题报告