提升coding能力------搜索专题(2)-----poj 1020

pku 1020 Anniversary Cake

题目地址:http://acm.pku.edu.cn/JudgeOnline/problem?id=1020

题目大意:

用小正方形填大正方形,问是否能刚刚填满,需要用一个技巧的DFS

深入分析:

待填坑。

务必,自己看题,自己理解题意,然后给自己一天的世界奋力写,看看能不能调试出来,就是TLE或者MLE也行,一天之后实在没思路或者不是最优法时,再看题解,并参考代码

#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
int big ,n;
int cake[20];
int col[50];
int DFS(int num)//还要放置num块
{
    if(num == 0)
        return  1;

    //从左往右扫先找出当前未填满的行的第一个空白处,可能又多个,

    int minc = 100 ,pos ;
    for(int i = 1 ; i <= big; i++ )
        if(col[i] < minc)
        {
            minc = col[i];

            pos = i;
        }
    //找出这个缺口的最大横向拓展距离


    int width = 1;
    for(int i = pos + 1 ;i <= big ;i++)
        if(col[i] == col[pos])
            width++;
        else
            break;



    //尝试填满这个空白处,从大到小选一个,或者从小到大依次选一个,只要放进去不会越界
    //而且使空白处的横向长度减少了,那么就可以了。

    for(int  i = 10 ;i >= 1; i-- )
    {


            if( cake[i]>=1 && big - col[pos] >= i && width >=i )
            {

                cake[i]--;

                for(int j = pos ; j <= pos + i -1 ; j++)
                      col[j] += i;

                if(DFS(num - 1))
                    return 1;

                //否则回溯
                cake[i]++;

                for(int j = pos ; j <= pos + i -1 ;j++)
                     col[j] -=i;

            }


    }




    return 0;





}
int main()
{
    int t;
    cin >> t;
    while(t--)
    {

        memset(cake,0,sizeof(cake));
        memset(col,0,sizeof(col));

        cin >> big >> n;
        int temp;
        for(int i = 1; i <= n ;i++ )
        {
            cin >> temp;
            cake[temp]++; //合并,省的排序

        }

        if(DFS(n))
            cout << "KHOOOOB!" << endl;

        else
            cout << "HUTUTU!" << endl;


    }


}


 

猜你喜欢

转载自blog.csdn.net/CCSGTC/article/details/82253971