部分内容转自:http://starforever.blog.hexun.com/2097115_d.html
题意:给定四个矩形,矩形在平面中只能垂直或者水平放置,而且不能有重叠。求能把这四个矩形都框在里面的封闭矩形的最小面积s。这样的矩形可能不止一个,求出所有这些封闭矩形的边长情况p, q。p<q且p*q=s。输出的结果按照p递增的顺序排列。
解题思路:
- 完全可以参照http://starforever.blog.hexun.com/2097115_d.html这篇文章中的内容求解。
- 文中对矩形的放法进行了布局分类,并且标出了1、2、3、4
- 令四个矩形的水平长度分别为w1~w4,垂直长度分别为h1~h4。对四个矩形的边长进行枚举,就能模拟矩形的各种放法(包括横放竖放以及所在的位置),总共会有8*6*4*2=384种取法。
- 对384种取法进行遍历,在遍历过程中求出每种取法下各种布局的封闭矩形面积,并更新最小值。同时将封闭矩形的变边长存于数组中。
- 最后对这个数组进行去重和排序就能得到最终的结果
代码:
/*
ID: zc.rene1
LANG: C
PROG: packrec
*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<stdarg.h>
int min_area=200*200;
int result_width[8*6*4*2*9];
int result_height[8*6*4*2*9];
int result_index=0;
int max_val(int num, ...){
va_list ap;
int i, max=-1, temp;
va_start(ap, num);
for(i=0; i<num; i++){
temp=va_arg(ap, int);
if(max<=temp) max=temp;
}
va_end(ap);
return max;
}
void set_tag_h(int tag[], int h[], int num, int index){
tag[num]=1;
if(num<4){
tag[num+4]=1;
h[index]=num+4;
}
else{
tag[num-4]=1;
h[index]=num-4;
}
}
void clear_tag(int tag[], int num){
tag[num]=0;
if(num<4){
tag[num+4]=0;
}
else{
tag[num-4]=0;
}
}
void do_work(int length[], int w[], int h[]){
int i, width, height, temp_area;
int w_c[4], h_c[4];
for(i=0; i<4; i++){
w_c[i]=length[w[i]];
h_c[i]=length[h[i]];
}
//case1
width=w_c[0]+w_c[1]+w_c[2]+w_c[3];
height=max_val(4, h_c[0], h_c[1], h_c[2], h_c[3]);
temp_area=width*height;
if(temp_area<=min_area){
if(temp_area<min_area){
result_index=0;
}
result_width[result_index]=width<height?width:height;
result_height[result_index]=height>width?height:width;
result_index++;
min_area=temp_area;
}
//case2
width=max_val(2, w_c[0]+w_c[1]+w_c[2], w_c[3]);
height=h_c[3]+max_val(3, h_c[0], h_c[1], h_c[2]);
temp_area=width*height;
if(temp_area<=min_area){
if(temp_area<min_area){
result_index=0;
}
result_width[result_index]=width<height?width:height;
result_height[result_index]=height>width?height:width;
result_index++;
min_area=temp_area;
}
//case3
width=max_val(2, w_c[0], w_c[1])+w_c[2]+w_c[3];
height=max_val(3, h_c[0]+h_c[1], h_c[2], h_c[3]);
temp_area=width*height;
if(temp_area<=min_area){
if(temp_area<min_area){
result_index=0;
}
result_width[result_index]=width<height?width:height;
result_height[result_index]=height>width?height:width;
result_index++;
min_area=temp_area;
}
//case4
width=w_c[0]+max_val(2, w_c[3], w_c[1]+w_c[2]);
height=max_val(2, h_c[0], max_val(2, h_c[1], h_c[2])+h_c[3]);
temp_area=width*height;
if(temp_area<=min_area){
if(temp_area<min_area){
result_index=0;
}
result_width[result_index]=width<height?width:height;
result_height[result_index]=height>width?height:width;
result_index++;
min_area=temp_area;
}
//case5
height=max_val(2, h_c[0]+h_c[2], h_c[1]+h_c[3]);
if(h_c[2]>=(h_c[1]+h_c[3])){
width=max_val(2, w_c[0], w_c[2]+max_val(2, w_c[1], w_c[3]));
}
else if(h_c[2]>h_c[3]&&h_c[2]<(h_c[1]+h_c[3])){
width=max_val(3, w_c[0]+w_c[1], w_c[1]+w_c[2], w_c[2]+w_c[3]);
}
else if(h_c[2]==h_c[3]){
width=max_val(2, w_c[0]+w_c[1], w_c[2]+w_c[3]);
}
else if(h_c[2]<h_c[3]&&h_c[3]<(h_c[0]+h_c[2])){
width=max_val(3, w_c[0]+w_c[1], w_c[0]+w_c[3], w_c[2]+w_c[3]);
}
else{
width=max_val(2, w_c[1], w_c[3]+max_val(2, w_c[0], w_c[2]));
}
temp_area=width*height;
if(temp_area<=min_area){
if(temp_area<min_area){
result_index=0;
}
result_width[result_index]=width<height?width:height;
result_height[result_index]=height>width?height:width;
result_index++;
min_area=temp_area;
}
}
void sort_result(){
int i, j, temp;
for(j=result_index-1; j>0; j--){
for(i=0; i<j; i++){
if(result_width[i]>result_width[i+1]){
temp=result_width[i];
result_width[i]=result_width[i+1];
result_width[i+1]=temp;
temp=result_height[i];
result_height[i]=result_height[i+1];
result_height[i+1]=temp;
}
}
}
}
int main(void){
FILE *fin=fopen("packrec.in", "r");
FILE *fout=fopen("packrec.out", "w");
int length[8], tag[8], w[4], h[4];
int i, j, k, m, prev=-1;
for(i=0; i<4; i++){
fscanf(fin, "%d %d", &length[i], &length[4+i]);
}
memset(tag, 0, 8*sizeof(int));
for(i=0; i<8; i++){
w[0]=i;
set_tag_h(tag, h, i, 0);
for(j=0; j<8; j++){
if(tag[j]==1) continue;
w[1]=j;
set_tag_h(tag, h, j, 1);
for(k=0; k<8; k++){
if(tag[k]==1) continue;
w[2]=k;
set_tag_h(tag, h, k, 2);
for(m=0; m<8; m++){
if(tag[m]==1) continue;
w[3]=m;
set_tag_h(tag, h, m, 3);
do_work(length, w, h);
clear_tag(tag, m);
}
clear_tag(tag, k);
}
clear_tag(tag, j);
}
clear_tag(tag, i);
}
sort_result();
fprintf(fout, "%d\n", min_area);
for(i=0; i<result_index; i++){
if(result_width[i]==prev) continue;
fprintf(fout, "%d %d\n", result_width[i], result_height[i]);
prev=result_width[i];
}
return 0;
}