/*
ID: lucien23
PROG: packrec
LANG: C++
*/
/*
*深度优先遍历,找出最优解
*此题是我做USACO到目前为止花时间最多的
*很郁闷
**/
#include<iostream>
#include<fstream>
#include<vector>
#include<algorithm>
using namespace std;
typedef struct Rectangle
{
int width;
int height;
}Rectangle;
bool comparer1(Rectangle rect1,Rectangle rect2)
{
return rect1.height*rect1.width<rect2.height*rect2.width;
}
bool comparer2(Rectangle rect1,Rectangle rect2)
{
return rect1.width<rect2.width;
}
int main()
{
ifstream infile("packrec.in");
ofstream outfile("packrec.out");
if(!infile || !outfile)
{
cout<<"file operation failure!"<<endl;
return -1;
}
Rectangle rects[4];
int width,height;
for (int i=0;i<4;i++)
{
infile>>width>>height;
rects[i].width=min(width,height);
rects[i].height=max(width,height);
}
//测试6种基本布局(实际只有5中,4,5是相同的)
//对每一种布局依次遍历每种矩阵的摆放方式
// 每个矩阵都可能旋转90度,共4!*2^4=384种
// 找出最小的大矩阵
vector<Rectangle> vectorRect;
Rectangle rect;
for (int i=0;i<4;i++)
{
int icount=1;
while(icount<=2){
if(icount==2)//矩阵旋转90度
{
int temp=rects[i].height;
rects[i].height=rects[i].width;
rects[i].width=temp;
}
for (int j=0;j<4;j++)
{
if(i==j)
continue;
int jcount=1;
while(jcount<=2){
if(jcount==2)
{
int temp=rects[j].height;
rects[j].height=rects[j].width;
rects[j].width=temp;
}
for (int k=0;k<4;k++)
{
if(i==k || j==k)
continue;
int kcount=1;
while(kcount<=2){
if(kcount==2)
{
int temp=rects[k].height;
rects[k].height=rects[k].width;
rects[k].width=temp;
}
for (int t=0;t<4;t++)
{
if(i==t || j==t || k==t)
continue;
int tcount=1;
while(tcount<=2){
if(tcount==2)
{
int temp=rects[t].height;
rects[t].height=rects[t].width;
rects[t].width=temp;
}
//布局一
height=max(max(max(rects[i].height,rects[j].height),rects[k].height),rects[t].height);
width=rects[i].width+rects[j].width+rects[k].width+rects[t].width;
rect.height=max(height,width);
rect.width=min(height,width);
vectorRect.push_back(rect);
//布局二
if(rects[t].height>rects[j].width+rects[k].width)
{
height=max(max(rects[i].height,rects[j].height),rects[k].height)+rects[t].width;
width=max(rects[i].width+rects[j].width+rects[k].width,rects[t].height);
rect.height=max(height,width);
rect.width=min(height,width);
vectorRect.push_back(rect);
}
//布局三
if(rects[t].height>rects[j].width)
{
height=max(max(rects[i].height,rects[j].height)+rects[t].width,rects[k].height);
width=max(rects[i].width+rects[j].width,rects[t].height)+rects[k].width;
rect.height=max(height,width);
rect.width=min(height,width);
vectorRect.push_back(rect);
}
//布局四
height=max(max(rects[i].height,rects[k].height),rects[j].height+rects[t].height);
width=max(rects[j].width,rects[t].width)+rects[i].width+rects[k].width;
rect.height=max(height,width);
rect.width=min(height,width);
vectorRect.push_back(rect);
//布局五,最麻烦的,左右两边其实是对称的情况,所以只考虑一边就行
if(rects[k].height>=rects[t].height)
{
if(rects[i].height+rects[t].height>rects[k].height && rects[i].width<=rects[t].width)
{//这个条件通过镜像反射代表了两个条件
width=max(rects[i].width+rects[j].height,rects[k].width+rects[t].width);
}
}else if(rects[j].width+rects[k].height<=rects[t].height){
width=max(max(rects[j].height,rects[k].width)+rects[t].width,rects[i].width);
}else{
width=max(rects[i].width,rects[t].width)+max(rects[j].height,rects[k].width);
}
height=max(rects[i].height+rects[t].height,rects[j].width+rects[k].height);
rect.height=max(height,width);
rect.width=min(height,width);
vectorRect.push_back(rect);
tcount++;
}
}
kcount++;
}
}
jcount++;
}
}
icount++;
}
}
sort(vectorRect.begin(),vectorRect.end(),comparer1);//按面积从小到大排序
vector<Rectangle>::iterator it=vectorRect.begin();
for (it++;it!=vectorRect.end();it++)
{
if(it->height*it->width > (it-1)->height*(it-1)->width)
break;
}
sort(vectorRect.begin(),it,comparer2);//将最小面积的方案按宽度从小到大排序
vector<Rectangle>::iterator it2=vectorRect.begin();
outfile<<it2->height*it2->width<<endl;
outfile<<it2->width<<" "<<it2->height<<endl;
for (it2++;it2!=it;it2++)
{
if(it2->width==(it2-1)->width)
continue;
outfile<<it2->width<<" "<<it2->height<<endl;
}
infile.close();
outfile.close();
return 0;
}
USACO Section 1.4 Packing Rectangles
最新推荐文章于 2024-02-01 10:39:25 发布