嗜血魂K

导航

1.4 Packing Rectangles

参见大牛博客:http://starforever.blog.hexun.com/2097115_d.html

自己是无论如何也想不到那里去的,特别是最后一种情况的分类讨论

不仅如此,此题编码难度也非常的大,这给本来基础不好的我带来很大压力。还是决定先围观下白书生成全排列部分,周四再来写此题

基本思路:
读入数据
/*
生成每一组可能
数组rec 0..3存放编号,调用next_permutation不断生成
编写swap_permutation(int k){
 if(k == 4) cal();
 else swap_permutation(k+1); swap(x,y); swap_permutation(k+1);
}//生成长宽组合
*/
生成4个方块对应图片编号的全排列
对于每一个排列:
每一个方块长宽对换 2*2*2*2 种可能
对于每一种可能:
分别调用函数layout1-5
layout{
 …………
 S < minS updateS
}

用结构体+minS+minans 更新
maxones{
 int p,q;
}
一旦大于minS就清空数组,minans=0
更新时让p = min(w,h) q = max(w,h)

搜索完毕后,以p为关键字排序

输出时判重
//记录只用记录一条边!

====================================AC后==============================================

终于搞定这题了,写这题是卡了3-4天,接触这题的话就是1week了。

要上课了。。先不总结了。。

/*
ID:y7276571
LANG: C++
TASK: packrec
*/
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define MAXN 1000
#define left(k) topack[no[k]].left
#define right(k) topack[no[k]].right
using namespace std;
struct rec{
int left, right;
};
int no[] = {0,1,2,3}, minS = (2 << 13)-1, suited[1000], pos = 0;
rec topack[4];
int max(int x,int y)
{
return x > y ? x : y;
}
int min(int x,int y)
{
return x < y ? x : y;
}
void update(int S, int len)
{
if(S < minS) { minS = S; memset(suited, 0, MAXN); pos = 0; }
else if(S == minS) suited[pos++] = len;
}
void layout1()
{
int w = left(0)+left(1)+left(2)+left(3), h = max(right(0), max(right(1),max(right(2),right(3))));
int S = w*h;
// printf("S = %d, w = %d, h = %d\n", S, w, h);
update(S, min(w,h));
}

void layout2()
{
int w = max(left(0)+left(1)+left(2), left(3)), h = max(right(0),max(right(1),right(2)))+right(3);
int S = w*h;
update(S, min(w,h));
}

void layout3()
{
int w = max(left(0)+left(1),left(2))+left(3), h = max(right(0)+right(2),max(right(1)+right(2),right(3)));
int S = w*h;
update(S, min(w,h));
}

void layout4()
{
int w = left(0)+left(1)+max(left(2),left(3)), h = max(right(0),max(right(2)+right(3),right(1)));
int S = w*h;
update(S, min(w,h));
}

void layout5()
{
int w,h = max(right(1)+right(3),right(0)+right(2));
if(right(2) >= right(1)+right(3)) w = max(left(0),max(left(2)+left(1),left(2)+left(3)));
else if(right(2) > right (3) && right(2) < right(1)+right(3)) w = max(left(0)+left(1),max(left(1)+left(2),left(2)+left(3)));
else if(right(3) > right(2) && right(3) < right(0)+right(2)) w = max(left(0)+left(1),max(left(0)+left(3),left(2)+left(3)));
else if(right(3) >= right(0)+right(2)) w = max(left(1),max(left(0)+left(3),left(2)+left(3)));
else w = max(left(0)+left(1),left(2)+left(3));
int S = w*h;
update(S, min(w,h));
}

void cal()
{
// for(int i = 0; i < 4; i++) cout << i << ":" << left(i) << " " << right(i) << endl;
layout1(); layout2(); layout3();
layout4(); layout5();
}
void swap(int k)
{
int temp = topack[k].right;
topack[k].right = topack[k].left;
topack[k].left = temp;
}
void swap_permutation(int k)
{
if(k == 4) cal();
else{
swap_permutation(k+1);
swap(k);
swap_permutation(k+1);
swap(k);
}
}
void work()
{
do{
swap_permutation(0);
}while(next_permutation(no, no+4));
}
int cmp(const void *a, const void *b)
{
return *(int *)a - *(int *)b;
}
int main()
{
freopen("packrec.in", "r", stdin);
freopen("packrec.out", "w", stdout);
for(int i = 0; i < 4; i++) cin >> topack[i].left >> topack[i].right;
work();
cout << minS << endl;
qsort(suited, pos, sizeof(int), cmp);
int temp = -1;
for(int i = 0; i < pos; i++)
if(temp != suited[i])
{
// cout << "I = " << i << endl;
temp = suited[i];
cout << temp << " " << minS/temp << endl;
}
return 0;
}

 

posted on 2011-12-06 13:48  嗜血魂K  阅读(193)  评论(0编辑  收藏  举报