USACO 1.4.1Packing Rectangles

// 123.cpp : 定义控制台应用程序的入口点。
//
/*
ID: maiyuet1
PROG: packrec
LANG: C++
*/

//模拟示例中的6种情况

//#include "stdafx.h"
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <queue>
#include <cstring>
#include <cmath>
using namespace std;

typedef struct rectangle
{
	int length;
	int width;
	int area;
	const bool operator < (const struct rectangle& a) const 
	{
		if(area == a.area)
		{
			return width > a.width;
		}
		return area > a.area;
	}
}Rec;

priority_queue<Rec>Q;

void swap(int &a, int &b)
{
	int c;
	c = a;
	a = b;
	b = c;
}

int max(int a, int b)
{
	return a > b ? a : b;
}

void push(Rec rec,int type)
{
	if(rec.width > rec.length)
	{
		swap(rec.width,rec.length);
	}
	rec.area = rec.length * rec.width;
	if(Q.empty() || (rec.area == Q.top().area && rec.length != Q.top().length))
	{
		Q.push(rec);
	}
	else if(rec.area < Q.top().area)
	{
		while(!Q.empty())
		{
			Q.pop();
		}
		Q.push(rec);
	}
}


void solve(Rec rec[], int order[], int type)
{
	Rec result;
	if(type == 1)   //图1的摆放方式
	{
		result.width = rec[order[0]].width + rec[order[1]].width + rec[order[2]].width + rec[order[3]].width;
		result.length =max( max(max(rec[order[0]].length,rec[order[1]].length),rec[order[2]].length),rec[order[3]].length);
	}
	else if(type == 2)  //图2的摆放方式
	{
		result.width = max(rec[order[0]].width+rec[order[1]].width+rec[order[2]].width,rec[order[3]].width);
		result.length = max(max(rec[order[0]].length,rec[order[1]].length),rec[order[2]].length)+rec[order[3]].length;
	}
	else if(type == 3)  //图3的情况
	{
		result.width = max(rec[order[0]].width+rec[order[1]].width,rec[order[2]].width) + rec[order[3]].width;
		result.length = max(max(rec[order[0]].length,rec[order[1]].length)+rec[order[2]].length,rec[order[3]].length);
	}
	else if(type == 4) //图中4,5为同一种情况
	{
		result.width = max(rec[order[0]].width,rec[order[1]].width) + rec[order[2]].width + rec[order[3]].width;
		result.length = max(max(rec[order[0]].length+rec[order[1]].length,rec[order[2]].length),rec[order[3]].length);
	}
	else if(type == 5) //第6个图,需要考虑所有情况
	{
		result.width = max(rec[order[0]].width+rec[order[2]].width,rec[order[1]].width+rec[order[3]].width);
		if(rec[order[2]].width < rec[order[3]].width && rec[order[0]].width > rec[order[1]].width &&
			rec[order[0]].length < rec[order[2]].length && rec[order[1]].length > rec[order[3]].length)
		{
			result.length = max(rec[order[0]].length + rec[order[1]].length,rec[order[2]].length + rec[order[3]].length);
		}
		else
		{
			result.length = max(rec[order[0]].length,rec[order[2]].length) + max(rec[order[1]].length,rec[order[3]].length);
		}

	}
	push(result,type);
}

void exchange(int a[], Rec rec[])
{
	for(int i=0; i<4; i++)
	{
		if(a[i] == 1)
		{
			swap(rec[i].width,rec[i].length);
		}
	}
}

int main()
{
	freopen("packrec.in","r",stdin);
	freopen("packrec.out","w",stdout);
	Rec rec[4];
	int order[4];
	int a[4];
	Rec flag[4];
	memset(a,0,sizeof(a));
	for(int i=0; i<4; i++)
	{
		cin>>rec[i].width>>rec[i].length;
		flag[i].width = rec[i].width;
		flag[i].length = rec[i].length;
	}
	for(int type=1; type<=5; type++)
	{
		order[0] = 0;
		order[1] = 1;
		order[2] = 2;
		order[3] = 3;
		do
		{
			//16种摆放方式(横竖摆放)
			for(a[0]=0; a[0]<2; a[0]++)
			{
				for(a[1]=0; a[1]<2; a[1]++)
				{
					for(a[2]=0; a[2]<2; a[2]++)
					{
						for(a[3]=0; a[3]<2; a[3]++)
						{
							exchange(a,rec);
							solve(rec,order,type);
							//还原
							for(int i=0; i<4; i++)
							{
								rec[i].width = flag[i].width;
								rec[i].length = flag[i].length;
							}
						}
					}
				}
			}
		}while(next_permutation(order,order+4)); //产生全排列
	}
	int area = Q.top().area;
	int width = 0;
	cout<<area<<endl;
	while(!Q.empty())
	{
		if(Q.top().area == area && Q.top().width != width)
		{
			cout<<Q.top().width<<" "<<Q.top().length<<endl;
			
		}
		width = Q.top().width;
		Q.pop();
	}
	return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值