USACO1.4Packing Rectangles(packrec)

        刚开始看感觉无从下手,后来看了分析才知道题目已经给出了只可能的6种组合情况,只需对每种情况中的四个矩形位置和摆放形式进行枚举。

 

/*
ID:jzzlee1
PROG:packrec
LANG:C++
*/
#include<iostream>
#include<fstream>
#include<cstring>
#include<cctype>
#include<cstdio>
using namespace std;
ifstream fin("packrec.in");
ofstream fout("packrec.out");
int total,MIN=32767,a[5][3],ans[100][3],a1,a2,a3,a4,b1,b2,b3,b4;
void Updata(int x,int y)
{
  if (x*y>MIN)
    return;
  if (x*y<MIN)
  {
    MIN=x*y;
    total=0;
  }
  if (x>y)
    swap(x,y);
  for (int i=1;i<=total;i++)
    if (x==ans[i][1]&&y==ans[i][2])
      return;
  total++;
  ans[total][1]=x; ans[total][2]=y;
}
void Work()
{
  int h1=a[a1][b1],h2=a[a2][b2],h3=a[a3][b3],h4=a[a4][b4],w1=a[a1][3-b1],w2=a[a2][3-b2],w3=a[a3][3-b3],w4=a[a4][3-b4],width,height;
 
  width=w1+w2+w3+w4;//case 1
  height=max(max(max(h1,h2),h3),h4);
  Updata(width,height);
 
  width=max(w1+w2+w3,w4);//case 2
  height=max(max(h1,h2),h3)+h4;
  Updata(width,height);
 
  width=max(w1+w2,w3)+w4;//case 3
  height=max(max(h1,h2)+h3,h4);
  Updata(width,height);
 
  width=w1+w2+max(w3,w4);//case 4 and case 5
  height=max(max(h1,h2),h3+h4);
  Updata(width,height);
 
  height=max(h1+h3,h2+h4);
  if (h3>=h2+h4)
     width=max(w1,w3+max(w2,w4));
  if (h3>h4&&h3<h2+h4)
     width=max(w1+w2,w3+max(w2,w4));
  if (h3<h4&&h4<h1+h3)
     width=max(w1+w2,w4+max(w1,w3));
  if (h4>=h1+h3)
     width=max(w2,w4+max(w1,w3));
  if (h3==h4)
     width=max(w1+w2,w3+w4);
  Updata(width,height);//case 6
}
int main()
{
	int i,j;
	for (i=1;i<5;i++)
    fin>>a[i][1]>>a[i][2];
	//cin>>a[i][1]>>a[i][2];
	//三重循环枚举每个矩形的摆放位置
	for (a1=1;a1<5;a1++)
		for (a2=1;a2<5;a2++)
			if (a1!=a2)
				for (a3=1;a3<5;a3++)
					if (a3!=a2&&a3!=a1)
					{
						a4=10-a1-a2-a3;
						//四重循环枚举每个矩形的摆放形式(横放或者竖放)
						for (b1=1;b1<3;b1++)
							for (b2=1;b2<3;b2++)
								for (b3=1;b3<3;b3++)
									for (b4=1;b4<3;b4++)
										Work();
					}
	for (i=1;i<total;i++)
		for (j=i+1;j<=total;j++)
			if (ans[i][1]>ans[j][1])
			{
				swap(ans[i][1],ans[j][1]);
				swap(ans[i][2],ans[j][2]);
			}
  //cout<<MIN<<endl;
  fout<<MIN<<endl;
  for (i=1;i<=total;i++)
   //cout<<ans[i][1]<<" "<<ans[i][2]<<endl;
  fout<<ans[i][1]<<" "<<ans[i][2]<<endl;
  return 0;
}

你可能感兴趣的:(USACO)