BAOWUNOJ正方形

正方形

题目描述

地上有 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思路

  1. 所有的树枝必须要全部用完
    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;
} 

点个赞支持一下煮啵吧QWQ