您的位置:首页 > 其它

poj 2362 square-----搜索+剪枝

2016-08-26 18:05 399 查看
题目大意
给出n根木棍,问是否可以首尾相连组成一个正方形。

算法
dfs+剪枝,合理巧妙的剪枝是避免TLE的关键;

1.特判,当木棍总长度不正好是4的倍数时,pass;

2.最长的木棍比边长小时,pass;

3.对木棍长排序,每次都从当前最大到小枚举,在同一条边中,之前放不下的木棍现在也一定放不下;

4.已经确定有解时,跳过剩下的过程;

5.三条边都可以,第四条一定可以。

代码实现

<span style="font-size:18px;">#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
bool f,vis[22];
int n,a[22],sum;
void dfs(int step,int ans,int st) //当前处理第几条边;总长度;当前最长木棍长;
{
if (f) return;
if (step>3)
{
f=1;
return;
}
for (int i=st;i;i--)
{
if(!vis[i]&&ans+a[i]<=sum)
{
ans+=a[i];
vis[i]=true;
if (ans==sum) dfs(step+1,0,n);
else dfs(step,ans,i-1); //更新当前最大木棍长;
if (f) return;
ans-=a[i];
vis[i]=0;
}
}
}

int main()
{
int t;
cin>>t;
while (t)
{
t--;
sum=0;
cin>>n;
memset(a,0,sizeof(a));
for (int i=1;i<=n;i++)
{
cin>>a[i];
sum+=a[i];
}
if (sum%4!=0)
{
cout<<"no"<<endl;
continue;
}
sum/=4;
memset(vis,false,sizeof(vis));
sort(a+1,a+n+1);
if (a
>sum)
{
cout<<"no"<<endl;
continue;
}
f=0;
dfs(1,0,n);
if (f) cout<<"yes"<<endl;
else cout<<"no"<<endl;
}
return 0;
}
</span>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  poj