USACO Packing Rectangles

1、#include <algorithm> 里面有自带的min()和max()函数

2、布局五实在是看不懂

3、使用了vector

vector<Rectangle> v;

v.push_back(rect);

sort(v.begin(), v.end(),cmp1);//按面积大小排序 
vector<Rectangle>::iterator it = v.begin();  
    
while( (it+1)!=v.end()){
          if( (it->height * it->width) < ((it+1)->height * (it+1)->width)) break;//取最小面积 
          it++;
    }

4、过滤重复的值:

vector<Rectangle>::iterator it2 = v.begin();
    
     printf("%d %d\n", it2->width, it2->height);
    for(it2++; it2 <= it; it2++){
            if(it2->width == (it2-1)->width) continue;//相等的值不输出 
            printf("%d %d\n", it2->width, it2->height);
    }



从http://blog.csdn.net/lucienduan/article/details/17022119

的代码:

/*
ID: nenusb1
PROG: packrec
LANG: C++
*/

/*
 *深度优先遍历,找出最优解
 **/

#include<iostream>
#include<fstream>
#include<vector>
#include<algorithm>
using namespace std;

typedef struct Rectangle
{
	int width;
	int height;
}Rectangle;

bool cmp1(Rectangle rect1,Rectangle rect2)
{
	return rect1.height*rect1.width<rect2.height*rect2.width;
}

bool cmp2(Rectangle rect1,Rectangle rect2)
{
	return rect1.width<rect2.width;
}

int main()
{
    freopen("packrec.in","r",stdin);
    freopen("packrec.out","w",stdout);

	Rectangle rects[4];
	int width,height;
	for (int i=0;i<4;i++)
	{
		 scanf("%d %d",&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> v;
	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);
									v.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);
										v.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);
										v.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);
									v.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);
									v.push_back(rect);

									tcount++;
								}
							}
							kcount++;
						}
					}
					jcount++;
				}
			}
			icount++;
		}
	}
	

    sort(v.begin(), v.end(),cmp1);//按面积大小排序 
    vector<Rectangle>::iterator it = v.begin();  
    
//    while(it< v.end()){
//              printf("%d %d\n", it->width, it->height);  
//         it++;           
//    }
//    printf("-------------------");
    
    
    it = v.begin();
          
    while( (it+1)!=v.end()){
          if( (it->height * it->width) < ((it+1)->height * (it+1)->width)) break;//取最小面积 
          it++;
    }
    
    sort(v.begin(), it+1, cmp2);//将最小面积的方案按宽度从小到大排序 
    
    printf("%d\n",it->height * it->width);//最小面积的值
    
    vector<Rectangle>::iterator it2 = v.begin();
    
     printf("%d %d\n", it2->width, it2->height);
    for(it2++; it2 <= it; it2++){
            if(it2->width == (it2-1)->width) continue;//相等的值不输出 
            printf("%d %d\n", it2->width, it2->height);
    } 
    
    return 0;
}


你可能感兴趣的:(USACO Packing Rectangles)