Anniversary Cake POJ - 1020

题目链接:点这里

    Nahid Khaleh decides to invite the kids of the "Shahr-e Ghashang" to her wedding anniversary. She wants to prepare a square-shaped chocolate cake with known size. She asks each invited person to determine the size of the piece of cake that he/she wants (which should also be square-shaped). She knows that Mr. Kavoosi would not bear any wasting of the cake. She wants to know whether she can make a square cake with that size that serves everybody exactly with the requested size, and without any waste.

Input

    The first line of the input file contains a single integer t (1 ≤ t ≤ 10), the  number of test cases, followed by input data for each test case. Each test case consist of a single line containing an integer s, the side of the cake, followed by an integer n (1 ≤ n ≤ 16), the number of cake pieces, followed by n integers (in the range 1..10) specifying the side of each piece.

Output

    There should be one output line per test case containing one of the words KHOOOOB! or HUTUTU! depending on whether the cake can be cut into pieces of specified size without any waste or not.

Sample Input

2
4 8 1 1 1 1 1 3 1 1
5 6 3 3 2 1 1 1

Sample Output

KHOOOOB!
HUTUTU!

题意:

给你一个size * size 的大蛋糕,问能否无浪费的分成n个小蛋糕.

思路:

    题目数据毕竟小,于是我们可以这样想,把大蛋糕看成多个 1 * 1 的小格子,小蛋糕也做同样的处理,然后我们把小蛋糕填入大蛋糕中,每次填依照从左向右,从下向上的顺序填充,这样就可以判断能否满足题意了.

代码:

#include
#include
#include
#include
#include
using namespace std;

int num[50];
int col[50];
int n,siz;

bool dfs(int curnum)
{
    if(curnum==n)
        return true;
    int minx=100;
    int cur=-1;
    for(int i=1;i<=siz;++i)//每次寻找最左边而且已经填充的蛋糕数量最小的格子
    if(minx>col[i]){
        minx=col[i];
        cur=i;
    }
    for(int t=10;t>=1;--t){//从大到小一次枚举蛋糕的尺寸
        if(num[t]==0)
            continue;
        if(siz-col[cur]>=t&&siz-cur+1>=t){
        //判断把当前尺寸的蛋糕填入格子中时是否越界,
            int wid=0;
            for(int i=cur;i<=cur+t-1;++i)//判断右边连续的t个格子能否满足
            if(col[cur]>=col[i])
                    ++wid;
            if(t<=wid){//如果能够满足
                num[t]--;  //大小为t的小蛋糕数目减一
                for(int j=cur;j<=cur+t-1;++j)
                    col[j]+=t;
                if(dfs(curnum+1))
                    return true;
                num[t]++;//回溯
                 for(int j=cur;j<=cur+t-1;++j)
                    col[j]-=t;
            }
        }
    }
    return false;
}

int main()
{
    int t;
    scanf("%d",&t);
    while(t--){
        memset(num,0,sizeof(num));
        memset(col,0,sizeof(col));
        scanf("%d %d",&siz,&n);
        int cnt=0;
        int area=0;
        for(int i=1;i<=n;++i){
            int s;
            scanf("%d",&s);
            num[s]++;//记录大小为s的蛋糕的个数
            area+=s*s;
            if(s>siz/2)
                ++cnt;
        }
        if(cnt>1||(area!=siz*siz)){
            cout<<"HUTUTU!"<continue;
            }
        if(dfs(0))
            cout<<"KHOOOOB!"<else cout<<"HUTUTU!"<return 0;
}

你可能感兴趣的:(算法之搜索)