[计蒜客(蓝桥杯省赛)]正方形 原创
题目来源 计蒜客程序设计竞赛基础课(蓝桥杯省赛)
算法标签 递归,剪枝
题目描述

提示

思路
1.一开始没看提示直接莽 ,4条边一起搜索,然后反应过来时间复杂度上天了。
2.根据一条边一条边搜索,满足长度,跳转到下一条边,加bool保证无重复
没有根据提示的错误答案
数据通过 4/10
#include<iostream>
using namespace std;
const int N=21;
int len[N],sum,n;
bool flag;
void dfs(int l1,int l2,int l3,int l4,int u)
{
if(l1>sum||l2>sum||l3>sum||l4>sum||u>n)return;
if(l1==sum&&l2==sum&&l3==sum&&u==n){flag=true;return;}
dfs(l1+len[u],l2,l3,l4,u+1);
dfs(l1,l2+len[u],l3,l4,u+1);
dfs(l1,l2,l3+len[u],l4,u+1);
dfs(l1,l2,l3,l4+len[u],u+1);
}
int main()
{
cin>>n;
for(int i=0;i<n;i++)cin>>len[i],sum+=len[i];
if(sum%4){cout<<"No";return 0;}
for(int i=n;i;i--)if(len[i]>sum/4){cout<<"No";return 0;}
sum/=4;
dfs(0,0,0,0,0);
if(flag)cout<<"Yes";else cout<<"No";
return 0;
}
题目代码
#include<iostream>
#include<algorithm>
using namespace std;
const int N=21;
int len[N],sum,n;
bool flag,st[N];
void dfs(int u,int s,int l)
{
if(flag)return;
if(l==3){flag=true;return;}//如果三遍满足,第四边肯定也满足,四边都满足则符合
if(s>sum)return;
if(s==sum)dfs(0,0,l+1);//一条边满足,过渡到下一条边
for(int i=u;i<n;i++)//爆搜+bool保证不重复
if(!st[i])
{
st[i]=true;
dfs(i+1,s+len[i],l);
st[i]=false;
}
}
int main()
{
cin>>n;
for(int i=0;i<n;i++)cin>>len[i],sum+=len[i];
if(sum%4){cout<<"No";return 0;}//%4不能除尽,则不是
for(int i=0;i<n;i++)if(len[i]>sum/4){cout<<"No";return 0;}//有一长大于边长则不是
sum/=4;
dfs(0,0,0);
if(flag){cout<<"Yes";}else cout<<"No";
return 0;
}

浙公网安备 33010602011771号