您的位置:首页 > 其它

Problem G --square (dfs+剪枝)

2012-06-24 16:19 260 查看
题意是给你一堆棍子。问你可不可以将他们组成正方形也就是可不可以平分成4份。

用dfs,值得注意的是此题的剪枝问题,直接上代码,看注释吧。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int s[25],sum,flag,n;
bool visit[25];
int cmp(const void *a,const void *b)
{
return *(int *)b-*(int *)a;
}
void dfs(int res,int ans,int x)
{
int i;
if(flag==1)	return ;
if(ans==4){flag=1;return ;}
if(res==0)	dfs(sum,ans+1,1);
for(i=x;i<=n;i++)  //强剪枝,排序后,棍子的长度是递减的,那么当你搜索到不满足条件的棍子时,只需回朔到它的前
//一个搜索位置,而不必回朔到初始位置1。(查找下一个位置时,可用二分加速,此题我就没写那么麻烦了)
{if(!visit[i] && res>=s[i])
{
visit[i]=true; res-=s[i];
dfs(res,ans,i+1);
visit[i]=false; res+=s[i];
}
}
}
int main()
{
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
int i,j,T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
sum=0;
for(i=1;i<=n;i++){
scanf("%d",&s[i]);
sum+=s[i];
}
if(sum%4!=0){    //如果不是4的倍数显然不能分成4份
printf("no\n");
continue;
}
sum/=4;
qsort(&s[1],n,sizeof(s[1]),cmp);  //为什么要排序上边已经说明了
//for(i=1;i<=n;i++)
//	printf("%d ",s[i]);
if(s[1]>sum){  //如果最大的棍子大于平均值那么也不能满足题意
printf("no\n");
continue;
}
flag=0;
memset(visit,false,sizeof(visit));
dfs(sum,0,1);
if(flag==1)
printf("yes\n");
else printf("no\n");
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: