深搜和回溯。关键是如何生成每种layout。有点恶心。一天内再也不想看自己写的这个代码了。有必要截个图告慰一下自己。
/* ID:chenjiong PROG:packrec LANG:C++ */ #include <stdio.h> #include <string.h> #include <algorithm> #include <iostream> using namespace std; int max(int a,int b) { return a > b ? a : b; } int min(int a,int b) { return a < b ? a : b; } typedef struct { int x; int y; }REC; REC p[4]; int order[4] = {0,1,2,3}; typedef struct { int x; int y; int area; }ANS; ANS q[5000]; int num; int X,Y; void dfs1(int cur) { if ( cur == 4 ) { q[num].x = X; q[num].y = Y; q[num].area = X * Y; num++; return; } X += p[order[cur]].x; int tmp = Y; Y = max(Y,p[order[cur]].y); dfs1(cur + 1); X -= p[order[cur]].x; Y = tmp; X += p[order[cur]].y; tmp = Y; Y = max(Y,p[order[cur]].x); dfs1(cur + 1); X -= p[order[cur]].y; Y = tmp; } void layout1() { sort(order,order + 4); do { X = 0; Y = 0; dfs1(0); } while ( next_permutation(order,order + 4) ); } void dfs2(int cur) { if ( cur == 4 ) { q[num].x = X; q[num].y = Y; q[num].area = X * Y; num++; return; } if ( cur == 3 ) { int t = X; X = max(X,p[order[cur]].x); Y += p[order[cur]].y; dfs2(cur + 1); Y -= p[order[cur]].y; X = t; t = X; X = max(X,p[order[cur]].y); Y += p[order[cur]].x; dfs2(cur + 1); Y -= p[order[cur]].x; X = t; } X += p[order[cur]].x; int tmp = Y; Y = max(Y,p[order[cur]].y); dfs2(cur + 1); X -= p[order[cur]].x; Y = tmp; X += p[order[cur]].y; tmp = Y; Y = max(Y,p[order[cur]].x); dfs2(cur + 1); X -= p[order[cur]].y; Y = tmp; } void layout2() { sort(order,order + 4); do { X = 0; Y = 0; dfs2(0); } while ( next_permutation(order,order + 4) ); } int con3_1 = 0; int con3_2 = 0; void dfs3(int cur) { if ( cur == 4 ) { q[num].x = X; q[num].y = Y; q[num].area = X * Y; num++; return; } if ( cur == 3) { int t = Y; X += p[order[cur]].x; Y = max(Y,p[order[cur]].y); dfs3(cur + 1); X -= p[order[cur]].x; Y = t; t = Y; X += p[order[cur]].y; Y = max(Y,p[order[cur]].x); dfs3(cur + 1); X -= p[order[cur]].x; Y = t; } if ( cur == 2 ) { int p1 = X; int p2 = Y; X = max(X,con3_1 + p[order[cur]].x); Y = max(Y,con3_2 + p[order[cur]].y); dfs3(cur + 1); X = p1; Y = p2; p1 = X; p2 = Y; X = max(X,con3_1 + p[order[cur]].y); Y = max(Y,con3_2 + p[order[cur]].x); dfs3(cur + 1); X = p1; Y = p2; } if ( cur == 1 ) { con3_1 = p[order[cur]].x; Y += p[order[cur]].y; dfs3(cur + 1); Y -= p[order[cur]].y; con3_1 = 0; con3_1 = p[order[cur]].y; Y += p[order[cur]].x; dfs3(cur + 1); Y -= p[order[cur]].x; con3_1 = 0; } if ( cur == 0 ) { con3_2 = p[order[cur]].y; X = p[order[cur]].x; Y = p[order[cur]].y; dfs3(cur + 1); X = 0; Y = 0; con3_2 = 0; con3_2 = p[order[cur]].x; X = p[order[cur]].y; Y = p[order[cur]].x; dfs3(cur + 1); X = 0; Y = 0; con3_2 = 0; } } void layout3() { sort(order,order + 4); do { X = 0; Y = 0; con3_1 = 0; con3_2 = 0; dfs3(0); } while ( next_permutation(order,order + 4) ); } void dfs4(int cur) { if ( cur == 4 ) { q[num].x = X; q[num].y = Y; q[num].area = X * Y; num++; return; } if ( cur == 1 ) { int t = X; X = max(X,p[order[cur]].x); Y += p[order[cur]].y; dfs4(cur + 1); Y -= p[order[cur]].y; X = t; t = X; X = max(X,p[order[cur]].y); Y += p[order[cur]].x; dfs4(cur + 1); Y -= p[order[cur]].x; X = t; } X += p[order[cur]].x; int tmp = Y; Y = max(Y,p[order[cur]].y); dfs4(cur + 1); X -= p[order[cur]].x; Y = tmp; X += p[order[cur]].y; tmp = Y; Y = max(Y,p[order[cur]].x); dfs4(cur + 1); X -= p[order[cur]].y; Y = tmp; } void layout4() { //layout4 and loyout5虽然在数学上是不同的摆放,但是覆盖面积一样,合并处理 sort(order,order + 4); do { X = 0; Y = 0; dfs4(0); } while ( next_permutation(order,order + 4) ); } int con6_1 = 0; int con6_2 = 0; int con6_3 = 0; int con6_4 = 0; int con6_5 = 0; void dfs6(int cur) { if ( cur == 4 ) { q[num].x = X; q[num].y = Y; q[num].area = X * Y; num++; return; } if ( cur == 3 ) { if ( con6_5 < con6_4 ) { int p1 = X; int p2 = Y; X = max(X,con6_3 + p[order[cur]].x); Y = max(Y,con6_5 + p[order[cur]].y); dfs6(cur + 1); X = p1; Y = p2; p1 = X; p2 = Y; X = max(X,con6_3 + p[order[cur]].y); Y = max(Y,con6_5 + p[order[cur]].x); dfs6(cur + 1); X = p1; Y = p2; } else { int p1 = X; int p2 = Y; X = max(X,con6_1 + p[order[cur]].x); Y = max(Y,con6_5 + p[order[cur]].y); dfs6(cur + 1); X = p1; Y = p2; p1 = X; p2 = Y; X = max(X,con6_1 + p[order[cur]].y); Y = max(Y,con6_5 + p[order[cur]].x); dfs6(cur + 1); X = p1; Y = p2; } } if ( cur == 2 ) { int t = Y; con6_5 = p[order[cur]].y; X += p[order[cur]].x; Y = max(Y,p[order[cur]].y); dfs6(cur + 1); X -= p[order[cur]].x; Y = t; con6_5 = 0; t = Y; con6_5 = p[order[cur]].x; X += p[order[cur]].y; Y = max(Y,p[order[cur]].x); dfs6(cur + 1); X -= p[order[cur]].y; Y = t; con6_5 = 0; } if ( cur == 1 ) { int t = X; con6_1 = min(X,p[order[cur]].x); con6_2 = p[order[cur]].x < X ? p[order[cur]].y : Y; con6_3 = max(X,p[order[cur]].x); con6_4 = p[order[cur]].x < X ? Y : p[order[cur]].y; Y += p[order[cur]].y; X = max(X,p[order[cur]].x); dfs6(cur + 1); X = t; Y -= p[order[cur]].y; con6_1 = 0; con6_2 = 0; con6_3 = 0; con6_4 = 0; t = X; con6_1 = min(X,p[order[cur]].y); con6_2 = p[order[cur]].y < X ? p[order[cur]].x : Y; con6_3 = max(X,p[order[cur]].y); con6_4 = p[order[cur]].y < X ? Y : p[order[cur]].x; Y += p[order[cur]].x; X = max(X,p[order[cur]].y); dfs6(cur + 1); X = t; Y -= p[order[cur]].x; con6_1 = 0; con6_2 = 0; con6_3 = 0; con6_4 = 0; } if ( cur == 0 ) { X = p[order[cur]].x; Y = p[order[cur]].y; dfs6(cur + 1); X = 0; Y = 0; X = p[order[cur]].y; Y = p[order[cur]].x; dfs6(cur + 1); X = 0; Y = 0; } } void layout6() { sort(order,order + 4); do { X = 0; Y = 0; con6_1 = 0; con6_2 = 0; dfs6(0); } while ( next_permutation(order,order + 4) ); } bool cmp(const ANS &a,const ANS &b) { if ( a.area < b.area ) return 1; else if ( a.area == b.area ) { if ( a.x < b.x) return 1; else return 0; } else return 0; } int main() { freopen("packrec.in","r",stdin); freopen("packrec.out","w",stdout); int i; for ( i = 0; i < 4; i++) scanf("%d%d",&p[i].x,&p[i].y); num = 0; layout1(); layout2(); layout3(); layout4(); layout6(); for ( i = 0; i < num; i++) { if ( q[i].x > q[i].y ) swap(q[i].x,q[i].y); } sort(q,q + num,cmp); int s = q[0].area; int pre = -1; printf("%d\n",s); for ( i = 0; i < num; i++) { if ( q[i].area == s ) { if ( q[i].x != pre ) { pre = q[i].x; printf("%d %d\n",q[i].x,q[i].y); } } else break; } return 0; }