刚开始想到的是枚举蛋糕的位置,从大蛋糕开始放,一定要左边,上边能贴住边界或别的蛋糕才认为是合法的位置,认为其与的方法比它差,wa了,这个贪心不是正确的
然后改成,只要有一边能贴住就认为是合法的位置,t了
看了其他人的方法,是找一个位置,然后枚举蛋糕往里边放,从左往右,从上往下放,这里很重要的一点是
记录蛋糕的方法,用一维的数组表示这一列放了几个格即可,但是还是t
还有一个问题,这样记录的话有可能出现后几列空余的位置更多,这样就不能往里边放蛋糕了
加上这一点就能ac了
#include <iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int a[20];
int ture,col[200],box[11];
int time;
int check(int t1,int t2,int s)
{
// for(int i=t1;i<=t2;i++)
// if(col[i]<s) return(0);
// return(1);
if(col[t1]<s) return(0);
for(int i=t1+1;i<=t2;i++)
if(col[i]<col[t1]) return(0);
return(1);
}
int work(int t1,int t2,int tmp)
{
for(int i=t1;i<=t2;i++)
col[i]+=tmp;
return(0);
}
int dfs(int t,int n,int s)
{
// printf("%d\n",++time);
// if(ture) return(0);
int min=0,tmp;
for(int i=1;i<=s;i++)
if(col[i]>min)
{
min=col[i];
tmp=i;
}
int max=0;
for(int i=10;i>=1;i--)
if(box[i])
{
max=i;
break;
}
if(col[tmp]<max) return(0);
int i=tmp;
for(int k=10;k>=1;k--)
if(box[k]&&i+k-1<=s)
{
if(check(i,i+k-1,k))
{
if(t==1) return(1);
work(i,i+k-1,-k);
box[k]--;
if(dfs(t-1,n,s))
return(1);
box[k]++;
work(i,i+k-1,k);
}
}
return(0);
}
int main()
{
int t;scanf("%d",&t);
while(t--)
{
int s; scanf("%d",&s);
int n; scanf("%d",&n);
memset(box,0,sizeof(box));
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
box[a[i]]++;
}
ture=0;
int sum=0;
for(int i=1;i<=n;i++)
sum+=a[i]*a[i];
if(sum!=s*s)
{
printf("HUTUTU!\n");
continue;
}
for(int i=1;i<=s;i++)
col[i]=s;
time=0;
if(dfs(n,n,s))
printf("KHOOOOB!\n");
else
printf("HUTUTU!\n");
}
return 0;
}