usaco 1.4.2 Packing Rectangles

图上描绘的就是所有的基本摆放方法

即4的全排列种方法+交换任意x,y=所有的摆放方法

/*
ID:    w.x.f.g1
PROG:  packrec
LANG:  C++
*/

#include<iostream>
#include<fstream>
#include<cstring>
using namespace std;

#define forn(a,n) for(int i=a;i<n;i++)
#define init() totx=0,toty=0;
#define update() tot.insert(totx,toty); \
if(tots>tot.s) tots=tot.s,memset(ans,0,sizeof(ans)); \
if(tots==tot.s) ans[tot.x]=1; 
struct node{
    int x,y,s;
    void insert(int a,int b){x=min(a,b),y=max(a,b),s=x*y;}
    void swap(){std::swap(x,y);}
}a[4],tot;
int ans[200],totx,toty,tots=0x3f3f3f;
int cal()
{
    node &a0=a[0],&a1=a[1],&a2=a[2],&a3=a[3];
    //kind 1
    init();
    forn(0,4) totx=max(totx,a[i].x),toty+=a[i].y;
    update();
    //kind 2
    init();
    forn(0,3) totx+=a[i].x,toty=max(toty,a[i].y);
    totx=max(totx,a3.y),toty+=a3.x;
    update();
    //kind 3
    init();
    totx=max(a0.x+a1.x,a3.y)+a2.x;
    toty=max(max(a0.y,a1.y)+a3.x,a2.y);
    update();
    //kind 4&&5;
    init();
    totx=a0.x+max(a1.x,a2.x)+a3.x;
    toty=max(max(a0.y,a3.y),a1.y+a2.y);
    update();
    //kind 6
    init();
    totx=max(max(a0.x,a3.x),a2.x+a1.x);
    toty=max(a0.y+a2.y,a1.y+a3.y);
    if(a2.y<a1.y) totx=max(totx,a1.x+a0.x);
    if(a0.y+a2.y>a1.y) totx=max(totx,a0.x+a3.x);
    if(a1.y<a2.y) totx=max(totx,a3.x+a2.x);
    update();
}
void dfs(int cur)
{
    if(cur==4) cal();
    else dfs(cur+1),a[cur].swap(),dfs(cur+1),a[cur].swap();
}
void solve(int cur)
{
    if(cur==4) dfs(0);
    else forn(cur,4) swap(a[cur],a[i]),solve(cur+1),swap(a[cur],a[i]);
}
int main()
{
    ifstream cin("packrec.in");
    ofstream cout("packrec.out");
    forn(0,4) cin>>a[i].x>>a[i].y;
    solve(0);
    cout<<tots<<endl;
    forn(0,200) if(ans[i]) cout<<i<<' '<<tots/i<<endl;
}


你可能感兴趣的:(usaco 1.4.2 Packing Rectangles)