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;
}
}