POJ百练 - 1017:装箱问题

链接:http://poj.grids.cn/practice/1017

说实话
这就是个简单的装箱子问题,很容易想清楚装箱子的过程,而且这个过程是满足贪心算法的,
所以只需要用代码模拟整个装箱子的过程即可,但是这样真的就足够了吗???
我刚开始就是用代码模拟这个手动过程了,虽然AC了,但是代码有150行左右,逻辑也显得过于复杂了,
得不偿失。。。整个过程是6*6的一个占一个箱子,5*5的也必须一个占一个箱子,但是需要补11个1*1的,
4*4的也是一个占一个箱子,但是需要补5个2*2的,如果2*2的不足够,则用1*1的代替,
3*3的4个占一个箱子,但是会有余数,可能余下1,2,3个3*3的箱子,这个时候必须非情况考虑,
1个3*3的需要和5个2*2的,7个1*1的组合,2个3*3的需要和3个2*2的,6个1*1的组合,
3个3*3的需要和1个2*2的,5个1*1的组合,最后考虑9个2*2的装一个箱子,多余的2*2用1*1的去填充尽量挤满一个箱子,
最后36个1*1的装一个箱子,余下的1*1的也必须占一个箱子。。。
这个过程说出来已经非常复杂了,更何况用代码写,我费了九牛二虎之力才写出来,WA了一次才AC了...

代码:
#include <stdio.h>
int main()
{
    int one, two, three, four, five, six;
    int num = 0;
    
    while (scanf("%d%d%d%d%d%d", &one, &two, &three, &four, &five, &six) == 6)
    {
        if (one == 0 && two == 0 && three == 0 && four == 0 && five == 0 && six == 0)
        {
            break;
        }
        
        num = six;
        num += five;
        if (one > five * 11)
        {
            one -= five * 11;
        }
        else
        {
            one = 0;
        }
        
        num += four;
        if (two > four * 5)
        {
            two -= four * 5;
        }
        else
        {
            if (one > four * 5 * 4 - two * 4)
            {
                one -= four * 5 * 4 - two * 4;
            }
            else
            {
                one = 0;
            }
            two = 0;
        }
        
        num += three / 4;
        three = three % 4;
        if (three == 1)
        {
            if (two > 5)
            {
                two -= 5;
                if (one > 7)
                {
                    one -= 7;
                }
                else
                {
                    one = 0;
                }
            }
            else
            {
                if (one > 27 - two * 4)
                {
                    one -= 27 - two * 4;
                }
                else
                {
                    one = 0;
                }
                two = 0;
            }
            ++num;
        }
        
        if (three == 2)
        {
            if (two > 3)
            {
                two -= 3;
                if (one > 6)
                {
                    one -= 6;
                }
                else
                {
                    one = 0;
                }
            }
            else
            {
                if (one > 18 - two * 4)
                {
                    one -= 18 - two * 4;
                }
                else
                {
                    one = 0;
                }
                two = 0;
            }
            ++num;
        }
        
        if (three == 3)
        {
            if (two > 1)
            {
                two -= 1;
                if (one > 5)
                {
                    one -= 5;
                }
                else
                {
                    one = 0;
                }
            }
            else
            {
                if (one > 9 - two * 4)
                {
                    one -= 9 - two * 4;
                }
                else
                {
                    one = 0;
                }
                two = 0;
            }
            ++num;
        }
        
        num += two / 9;
        two = two % 9;
        if (two)
        {
            if (one > 36 - two * 4)
            {
                one -= 36 - two * 4;
            }
            else
            {
                one = 0;
            }
            ++num;
        }
        
        num += one / 36;
        if (one % 36)
        {
            ++num;
        }
        
        printf("%d\n", num);
    }
    
    return 0;
}


这样的写法显然不好吧。。。首先,余下1,2,3个3*3时候需要填几个2*2的可以存储在数组里面,这样就可以不用写重复代码了,
如果再从整体考虑余下多少个格子,就不用用贪心算法模拟装箱子的过程了。。。
代码如下:
#include <stdio.h>
int main()
{
    int one, two, three, four, five, six;
    int num = 0;
    int twoPlace[4] = {0, 5, 3, 1};
    int remTwo, remOne;
    
    while (scanf("%d%d%d%d%d%d", &one, &two, &three, &four, &five, &six) == 6)
    {
        if (one == 0 && two == 0 && three == 0 && four == 0 && five == 0 && six == 0)
        {
            break;
        }
        
        num = six + five + four + (three + 3) / 4;
        remTwo = four * 5 + twoPlace[three % 4];
        if (two > remTwo)
        {
            num += (two - remTwo + 8) / 9;
        }
        
        remOne = 36 * num - 36 * six - 25 * five - 16 * four - 9 * three - 4 * two;
        if (one > remOne)
        {
            num += (one - remOne + 35) / 36;
        }
        
        printf("%d\n", num);
    }
    
    return 0;
}

posted on 2011-11-08 20:15 yx 阅读(1919) 评论(0)  编辑 收藏 引用 所属分类: 解题报告贪心


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2012年9月>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456

导航

统计

公告

常用链接

留言簿(3)

随笔分类

随笔档案

me

好友

同学

网友

搜索

最新评论

阅读排行榜

评论排行榜