USACO Section 1.4 packrec - 不是太好写的搜索水题

24 篇文章 0 订阅

     我也是开始题目看错了..以为是要着4个方块任意放置放出最小的矩阵...后来才发现也就6种情况...题目所给的那6个...输出也有点恶心..先输出最小面积..然后输出每个矩形的长宽..每个矩形输出的话先输出短边再输出长边...所有矩阵的顺序是先输出短边最短的..短边相等的输出长边较短的...依次..不重复输出矩阵...

     我的方法是先枚举好4个矩阵(那个以90度或者原样对应着哪一个)...所给的6个模块也给每个矩阵标好号~~然后就将没举出的四个矩阵和枚举好6个模块的矩阵标号对应起来...找到其中面积最小的...前5个还比较好...第6个要注意些...有好几个条件要来卡...


Program:

/* 
ID: zzyzzy12 
LANG: C++ 
TASK: packrec
*/  
#include<iostream>  
#include<stdio.h>  
#include<string.h>  
#include<math.h>  
#include<algorithm> 
#define oo 2000000000 
using namespace std;
struct node
{
     int x,y;       
}a[5],s[5],ansa[3001];
int i,ans,ansnum;  
bool used[5];
void update(int s,int x,int y)
{
     if (s==ans)
     {
          ansnum++;
          if (x<y)
          {
              ansa[ansnum].x=x;
              ansa[ansnum].y=y;      
          }else
          {
              ansa[ansnum].x=y;
              ansa[ansnum].y=x;        
          }                
     }else
     if (s<ans)
     {
          ans=s;
          ansnum=1;      
          if (x<y)
          {
              ansa[ansnum].x=x;
              ansa[ansnum].y=y;      
          }else
          {
              ansa[ansnum].x=y;
              ansa[ansnum].y=x;        
          }       
     }
     return;
}
void search(int k)
{
     int i;
     if (k==5)
     {
           int x,y;    
           x=s[1].x+s[2].x+s[3].x+s[4].x;
           y=max(max(max(s[1].y,s[2].y),s[3].y),s[4].y); 
           update(x*y,x,y);  ///---------------1
           x=max(s[1].x+s[2].x+s[3].x,s[4].x);
           y=max(max(s[1].y,s[2].y),s[3].y)+s[4].y;
           update(x*y,x,y);  ///---------------2
           x=max(s[1].x+s[2].x,s[3].x)+s[4].x;
           y=max(max(s[1].y,s[2].y)+s[3].y,s[4].y);
           update(x*y,x,y);  ///---------------3
           if (s[1].x<=s[3].x)
           {
                x=s[2].x+s[3].x+s[4].x;
                y=max(max(s[1].y+s[3].y,s[2].y),s[4].y);
                update(x*y,x,y);  ///---------------4            
           }      
           if (s[1].x<=s[2].x)
           {    
                x=s[2].x+s[3].x+s[4].x;
                y=max(max(s[1].y+s[2].y,s[3].y),s[4].y);
                update(x*y,x,y);  ///---------------5
           }
           if (s[1].x+s[2].x<=s[3].x+s[4].x && s[3].y<=s[4].y && s[1].x<=s[3].x)
           {
                x=s[3].x+s[4].x;
                y=max(s[1].y+s[3].y,s[2].y+s[4].y);                       
                update(x*y,x,y);  ///---------------6
           }
           return ;
     }
     for (i=1;i<=4;i++)
     if (!used[i])
     {
           used[i]=true;
           s[k]=a[i];
           search(k+1);
           s[k].x=a[i].y; s[k].y=a[i].x;
           search(k+1);
           used[i]=false;             
     }
}
bool cmp(node a,node b)
{
     if (a.x==b.x) return a.y<b.y;   
     return a.x<b.x; 
}
int main()  
{  
     freopen("packrec.in","r",stdin);  
     freopen("packrec.out","w",stdout);  
     for (i=1;i<=4;i++) scanf("%d%d",&a[i].x,&a[i].y);
     ans=oo;
     memset(used,false,sizeof(used));
     search(1);
     printf("%d\n",ans);
     sort(ansa+1,ansa+1+ansnum,cmp);
     printf("%d %d\n",ansa[1].x,ansa[1].y);
     for (i=2;i<=ansnum;i++) 
       if (ansa[i].x!=ansa[i-1].x || ansa[i].y!=ansa[i-1].y)
          printf("%d %d\n",ansa[i].x,ansa[i].y);
     return 0;    
}   


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值