正方形
题目描述
地上有 n 根长度不一的树枝,每根树枝长度均为整数。现在需要用全部树枝拼接成一个正方形,树枝不允许折断,只能多根拼接成一条边。请判断是否存在合法方案。
输入格式
第一行一个整数 n,代表树枝总数;
第二行输入 n 个整数,依次表示每根树枝的长度。
输出格式
如果可以拼成正方形,输出 yes;否则输出 no。
数据范围
4<=e<=20
单根树枝长度:1<=len<=1000
时空限制
时间限制:1 秒
内存限制:512 MB
样例输入与输出
样例 1
输入:
8
1 7 2 6 4 4 3 5
输出:
yes
解释:所有树枝总长 32,单边目标长度 8,可凑出 4 组和为 8 的树枝组合。
样例 2
输入:
5
10 20 30 40 50
输出:
no
解释:总长 150,无法整除 4,直接无解。
题意总结or思路
- 所有的树枝必须要全部用完
2.数据范围较小
3.如果树枝的总长度如果不能整除四就输出no
4.所以我们采用DFS加上剪枝来解决
大家心心念念的代码
#include<bits/stdc++.h>
using namespace std;
int n,nfc=0,mb=0;
int a[25];
void dfs(int x,int ans1,int ans2,int ans3,int ans4){
if(nfc==1)return;//如果找到就return,以下相同代码同理
if(x>n){
//cout<<ans1<<' '<<ans2<<' '<<ans3<<' '<<ans4<<endl;//测试
if(ans1==ans2&&ans2==ans3&&ans3==ans4){
nfc=1;//找到了
}
return;
}
int s=a[x];
if(ans1+s<=mb){//防止超过目标长度,以下同理
dfs(x+1,ans1+s,ans2,ans3,ans4);
}
if(nfc==1)return;
if(ans2+s<=mb){
dfs(x+1,ans1,ans2+s,ans3,ans4);
}
if(nfc==1)return;
if(ans3+s<=mb){
dfs(x+1,ans1,ans2,ans3+s,ans4);
}
if(nfc==1)return;
if(ans4+s<=mb){
dfs(x+1,ans1,ans2,ans3,ans4+s);
}
if(nfc==1)return;
}
bool cmp(int aa,int bb){
return aa>bb;//小技巧,从大到小是大于号,从小到大是小于号
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
mb+=a[i]; //求总长度
}
sort(a+1,a+n+1,cmp); //从大到小
if(mb%4!=0){//看能否分成四个相同的枝条
cout<<"no";
return 0;
}
mb/=4;
for(int i=1;i<=n;i++){
if(a[i]>mb){
cout<<"no";
return 0;
}
} //如果有任意的单个枝条长度大于mb就输出no,这里可以只用判断a[1]就行了,我这样子方便大家理解
dfs(1,0,0,0,0);//开始dfs
if(nfc==1)cout<<"yes";//找到就输出yes
else cout<<"no";//没找到就输出no
return 0;
}