首页 > 代码库 > POJ 1017 Packets

POJ 1017 Packets

这题可能是用贪心思想来写的,具体是不是我也不知道,自己对贪心也不是太清楚。之前好像写过,当时似乎没有写出来,不过,这次一下就有了思路。本来是想先装小的包裹,可是试了一下不行,有问题;于是改为先装大的包裹,如果有多余,再装小的,每次都这样,直到所有的包裹被装完为止。试了试,感觉没有什么问题。

代码写的可能有的乱,不过思路还是清楚的。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<stack>
#include<queue>
using namespace std;
int num[7];
bool visited[7][7];
bool judge(int size,int x,int y)//判断是否符合标准
{
    int a=size+x-1,b=size+y-1;
    if(a>6||b>6)//如果超过了6*6的范围显然不行
        return false;
    for(int i=x;i<=a;i++)
    {
        for(int j=y;j<=b;j++)//如果在所要求的区域中已经装过了,显然也不行
            if(visited[i][j])
            return false;
    }
    return true;
}
void set_true(int x,int y,int size)
{
    int a=size+x-1,b=size+y-1;
    for(int i=x;i<=a;i++)
        for(int j=y;j<=b;j++)//用来标志已经装过了的区域
        visited[i][j]=true;
}
bool isempty()
{
    for(int i=1;i<=6;i++)//判断是否还有包裹没装
        if(num[i]>0)
        return true;
    return false;
}
int main()
{
    while(true)
    {
        bool isok=false;
        for(int i=1;i<=6;i++)
        {
            scanf("%d",&num[i]);
            if(num[i]!=0)
                isok=true;
        }
        if(!isok)
            break;
        int ans=0;
        while(isempty())
        {
            memset(visited,false,sizeof(visited));
            for(int i=1;i<=6;i++)
            {
                for(int j=1;j<=6;j++)
                {
                    if(visited[i][j])
                        continue;
                    for(int k=6;k>=1;k--)//从大到小开始装
                    {
                        if(num[k]==0)
                            continue;
                        if(judge(k,i,j))
                        {
                            set_true(i,j,k);
                            num[k]--;
                            break;
                        }
                    }
                }
            }
            ans++;
        }
        printf("%d\n",ans);
    }
    return 0;
}


POJ 1017 Packets