USACO Training:Packing Rectangles

  这应该是usaco上遇到的第一个BT题,而且是极其BT。硬是让我纠结了一整天。尤其是最后一种情况,种类繁多,参考了大牛的结题报告才过的。各种WA。刚开始活生生写了300多行代码。AC的时候还有180行。肯定还有很大的优化空间。被此题搅的脑残了,懒得改进了。想不出IOI三个小时怎么写得出来。看来都是牛人。佩服!

  我开始觉得这个题应该就是枚举,但是要细心。因为只有4个矩形,4!X 2^4;空间要求不大。直接硬搜。但是主要是最后一种情况比较复杂,需要分为5类考虑。

  

    ( 1 ) h[2] == h[3];
        ( 2 ) h[2] >= h[0] + h[3];            
        ( 3 ) h[3] >= h[1] + h[2];                          
        ( 4 ) h[2] > h[3] && h[2] < h[0] + h[3];
        ( 5 ) 其他;

   以上图片及解题思路来自:http://blog.csdn.net/danmarner/archive/2006/11/14/1383092.aspx

/*
ID: like_091
PROG: packrec
LANG: C++
*/
#include<iostream>
#include<fstream>
using namespace std;
const int INF = 1000000;
short  c, d;
//四个矩形的边长
struct Node{
	int h, d;
}node[5];
//保存可能存在最小面积的队列
struct Set{
	int m, s, e;
}p[2000], q[2000];
//快排自定义函数
int cmp(const void *a, const void *b){
	Set *c = (Set *)a;
	Set *d = (Set *)b;
	if (c->m == d->m)
		return c->s - d->s;
	return c->m - d->m;
}
//入队
void enqueue(Set *p, int k, int m, int s, int e){
	p[k].m = m;
	p[k].s = s;
	p[k].e = e;
}
int main(){
	ifstream cin("packrec.in");
	ofstream cout("packrec.out");
	int x, y, mins, bu[10], hu[10], temp[10], totb, toth;
	short i, j, k, l, f;
	for (i = 1; i <= 4; i++)
		cin>>node[i].d>>node[i].h;
	for (i = 1; i <= 8; i++){
		if (i % 2){
			bu[i] = max(node[(i + 1) / 2].h, node[(i + 1) / 2].d);
			hu[i] = min(node[(i + 1) / 2].h, node[(i + 1) / 2].d);
			temp[i] = (i + 1) / 2;
		}else {
			bu[i] = min(node[i / 2].h, node[i / 2].d);
			hu[i] = max(node[i / 2].h, node[i / 2].d);
			temp[i] = i / 2;
		}
	}
	mins = INF;
	c = d = 0;
	for (i = 1; i <= 8; i++)
		for (j = 1; j <= 8; j++){
			if (temp[i] == temp[j])
				continue;
			for (k = 1; k <= 8; k++){
				if (temp[k] == temp[i] || temp[k] == temp[j])
					continue;
				for (l = 1; l <= 8; l++){
					if (temp[l] == temp[k] || temp[l] == temp[i] || temp[l] == temp[j])
						continue;
					//按第一种方法
					totb = bu[i] + bu[j] + bu[k] + bu[l];
					toth = max(hu[i], hu[j]);
					toth = max(toth, hu[k]);
					toth = max(toth, hu[l]);
					if (mins > totb * toth){
						mins = totb * toth;
						x = max(totb, toth);
						y = min(totb, toth);
					}else if (mins == totb * toth){
						enqueue(p, c, mins, min(totb, toth), max(totb, toth));
						c++;
					}
					//按第二种方法
					totb = bu[j] + bu[k] + bu[l];
					toth = max(hu[j], hu[k]);
					toth = max(toth, hu[l]);
					totb = max(totb, hu[i]);
					toth += bu[i];
					if (mins > toth *totb){
						mins = toth * totb;
						x = max(toth, totb);
						y = min(toth, totb);
					}else if (mins == toth *  totb){
						enqueue(p, c, mins, min(totb, toth), max(totb, toth));
						c++;
					}
					//按第三种方法
					toth = max(hu[i], bu[j] + max(hu[k], hu[l]));
					totb = bu[i] + max(hu[j], bu[k] + bu[l]);
					if (mins > toth * totb){
						mins = toth * totb;
						x = max(toth, totb);
						y = min(toth, totb);
					}else if (mins == toth *  totb){
						enqueue(p, c, mins, min(totb, toth), max(totb, toth));
						c++;
					}
					//按第四种方法
					totb = bu[i] + bu[j] + max(bu[k], bu[l]);
					toth = max(max(hu[i], hu[j]), hu[k] + hu[l]);
					if (mins > totb * toth){
						mins = totb * toth;
						x = max(totb, toth);
						y = min(totb, toth);
					}else if (mins == toth *  totb){
						enqueue(p, c, mins, min(totb, toth), max(totb, toth));
						c++;
					}
					//第五种和第四种是一样的
					//按第六种方法
					toth = max(hu[i] + hu[l], hu[j] + hu[k]);
				    if (hu[k] == hu[l])
						     totb = max(bu[j] + bu[i], bu[k] + bu[l]);
					else if (hu[k] >= hu[i] + hu[l]){ 
							 totb = max(bu[j], bu[i] + bu[k]);
							 totb = max(totb, bu[k] + bu[l]);
					}else if (hu[l] >= hu[j] + hu[k]){
							 totb = max(bu[i], bu[j] + bu[l]);
							 totb = max(totb, bu[k] + bu[l]);
                    }else if (hu[k] > hu[l] && hu[k] < hu[i] + hu[l]){
                             totb = max(bu[k] + bu[i], bu[k] + bu[l]);
                             totb = max(totb, bu[i] + bu[j]);
                    }else {
							 totb = max(bu[l] + bu[j], bu[l] + bu[k]);
							 totb = max(totb, bu[i] + bu[j]);
					}
					if (mins > totb * toth){
						mins = totb * toth;
						x = max(totb, toth);
						y = min(totb, toth);
					}else if (mins == toth *  totb){
						enqueue(p, c, mins, min(totb, toth), max(totb, toth));
						c++;
					}
				}
			}
		}
	enqueue(q, d, mins, y, x);
	d++;
	for (f = 0; f < c; f++)
		if (mins == p[f].m){
			enqueue(q, d, p[f].m, p[f].s, p[f].e);
			d++;
		}
	qsort(q, d, sizeof(q[0]), cmp);//对面积排序
	cout<<q[0].m<<endl;
	for (i = 0; i < d; i++)
		if (q[0].m == q[i].m && (!i || q[i].s != q[i - 1].s))
				cout<<q[i].s<<" "<<q[i].e<<endl;
	return 0;
}

                           

posted @ 2011-02-22 11:04  like@neu  阅读(326)  评论(0编辑  收藏  举报