您的位置:首页 > 其它

UVA311

2013-11-24 15:53 190 查看
这题是看别人的思路的。。。。

备注:

题目大意:

有1*1,2*2,3*3,4*4,5*5,6*6大小的盒子,要把它们装到6*6的盒子里,它们的高度都是相同的。求用最少的6*6盒子把所有尺寸的盒子都装起来。

分析与总结:

这一题是我在Volume 4. Algorithm Design这个专题中最后才做的一题,主要是因为没有思路。最好还是参考了别人的思路。

6*6的盒子中可以由各种尺寸的盒子来填满。可以有以下这些情况:

1个6*6

1个5*5+11个1*1

1个4*4+5个2*2(有空隙时优先放置2*2,如果没放完2*2的,剩下的就放置1*1)

放置3*3时,组合情况比较复杂。 没有放完3*3时,剩下的空隙也是优先尽可能多地放置2*2

当放置1个3*3时,还可以放置7个1*1和5个2*2

当放置2个3*3时,还可以放置6个1*1和3个2*2

当放置3个3*3时,还可以放置5个1*1和1个2*2

因为一个4*4,5*5,6*6只能放置在一个盒子里,所以有多少个这些,就需要多少个盒子来装。

然后因为3*3的可以和1*1和2*2的组合放置,所以也可以确定装完3*3需要的盒子。

那么在计算时,首先就可以确定放完3*3,4*4,5*5,6*6的盒子个数,假设是t个盒子。

然后这t个盒子中会有空隙,再优先把2*2的放置到t个盒子中的空隙中。如果这些空隙不能放完2*2的,那么就需要再增加盒子知道放完为止。最后在考虑放置1*1。

#include <iostream>
#include <cstdio>

using namespace std;

int a[7];
int three[4][2] = {{0, 0}, {7, 5}, {6, 3}, {5, 1}};

int main() {
    while (scanf("%d %d %d %d %d %d", &a[1], &a[2], &a[3], &a[4], &a[5], &a[6]) != EOF) {
        if (!a[1] && !a[2] && !a[3] && !a[4] && !a[5] && !a[6]) 
            break; 
        int num = (a[3] + 3) / 4 + a[4] + a[5] + a[6];
        a[1] -= a[5] * 11; 
        int left_2 = three[a[3] % 4][1] + a[4] * 5;

        if (left_2 >= a[2]) {
            a[1] -= three[a[3] % 4][0]; 
            a[2] -= left_2;
            a[1] += a[2] * 4; 
            if (a[1] > 0)
                num += (a[1] + 35) / 36; 
        }
        else {
            a[1] -= three[a[3] % 4][0];
            a[2] -= left_2; 
            num += (a[2] + 8) / 9; 
            a[1] -= (9 - a[2] % 9) * 4;
            if (a[1] > 0) 
                num += (a[1] + 35) / 36; 
        } 
        printf("%d\n", num);
    } 
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: