Usaco Training Section 6.2Packing Rectangles

Packing Rectangles 铺放矩形块
IOI 95
给定4 个矩形块,找出一个最小的封闭矩形将这4 个矩形块放入,但不得相互重叠.所谓最小矩形指
该矩形面积最小.
所有4 个矩形块的边都与封闭矩形的边相平行,图1 示出了铺放4 个矩形块的6 种方案.这6 种方案
仅只是可能的基本铺放方案.因为其它方案能由基本方案通过旋转和镜像反射得到.
可能存在满足条件且有着同样面积的各种不同的封闭矩形,你应该输出所有这些封闭矩形的边长.

PROGRAM NAME: packrec
INPUT FORMAT
共有4 行.每一行用两个正整数来表示一个给定的矩形块的两个边长.矩形块的每条边的边长范围
最小是1,最大是50.
SAMPLE INPUT (file packrec.in)
1 2
2 3
3 4
4 5
OUTPUT FORMAT
总行数为解的总数加1.第一行是一个整数,代表封闭矩形的最小面积(子任务A).接下来的每一行
都表示一个解,由数P 和数Q 来表示,并且P≤Q(子任务B).这些行必须根据P 的大小按升序排列,P
小的行在前,大的在后.且所有行都应是不同的.
SAMPLE OUTPUT (file packrec.out)
40
4 10
5 8

分析:思路很明确,分6种情况讨论,其实4和5是等价的。主要是第6种太烦了。我们来摘一段题解:

/*
     * schema 6: first two pressed next to each other, next two on top, like: 
     * 2 3
     * 0 1
     */
    big.ht = max(r[0].ht+r[2].ht, r[1].ht+r[3].ht);
    big.wid = r[0].wid + r[1].wid;

    /* do 2 and 1 touch? */
    if(r[0].ht < r[1].ht)
        big.wid = max(big.wid, r[2].wid+r[1].wid);
    /* do 2 and 3 touch? */
    if(r[0].ht+r[2].ht > r[1].ht)
        big.wid = max(big.wid, r[2].wid+r[3].wid);
    /* do 0 and 3 touch? */
    if(r[1].ht < r[0].ht)
        big.wid = max(big.wid, r[0].wid+r[3].wid);

    /* maybe 2 or 3 sits by itself */
    big.wid = max(big.wid, r[2].wid);
    big.wid = max(big.wid, r[3].wid);

Usaco Training Section 6.2Packing Rectangles_第1张图片

#include
#define ll long long
#define ull unsigned long long
#define inf 2147483647
#define mp make_pair
#define pii pair
#define pb push_back
#define r1 rt<<1
#define r2 rt<<1|1
#define ld long double
using namespace std;

inline int read(){
	int x=0,f=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^'0'),c=getchar();
	return x*f;
}

int ans=inf,x[5],y[5],b[5];
set s;

inline void work(int u,int v){
	if(u*vv) swap(u,v);
		s.insert(mp(u,v));
	}
	else if(u*v==ans){
		if(u>v) swap(u,v);
		s.insert(mp(u,v));
	}
}

int main()
{
	freopen("packrec.in","r",stdin);
	freopen("packrec.out","w",stdout);
	int maxx=0,maxy=0;
	for(int i=1;i<=4;++i) x[i]=read(),y[i]=read(),b[i]=i;
	do{
		for(int a1=0;a1<2;++a1)
		for(int a2=0;a2<2;++a2)
		for(int a3=0;a3<2;++a3)
		for(int a4=0;a4<2;++a4){
			if(a1) swap(x[b[1]],y[b[1]]);
			if(a2) swap(x[b[2]],y[b[2]]);
			if(a3) swap(x[b[3]],y[b[3]]);
			if(a4) swap(x[b[4]],y[b[4]]);
			work(x[b[1]]+x[b[2]]+x[b[3]]+x[b[4]],max(max(max(y[b[1]],y[b[2]]),y[b[3]]),y[b[4]]));
			work(max(x[b[1]]+x[b[2]]+x[b[3]],x[b[4]]),max(max(y[b[1]],y[b[2]]),y[b[3]])+y[b[4]]);
			work(max(x[b[1]]+x[b[2]],x[b[3]])+x[b[4]],max(max(y[b[1]],y[b[2]])+y[b[3]],y[b[4]]));
			work(max(x[b[1]],x[b[2]])+x[b[3]]+x[b[4]],max(max(y[b[1]]+y[b[2]],y[b[3]]),y[b[4]]));
			int z=x[b[1]]+x[b[2]];
			if(y[b[1]]y[b[2]]) z=max(z,x[b[3]]+x[b[4]]);
			if(y[b[2]]

 

你可能感兴趣的:(UsacoTraining)