https://leetcode-cn.com/problems/matchsticks-to-square/
还记得童话《卖火柴的小女孩》吗?现在,你知道小女孩有多少根火柴,请找出一种能使用所有火柴拼成一个正方形的方法。不能折断火柴,可以把火柴连接起来,并且每根火柴都要用到。
输入为小女孩拥有火柴的数目,每根火柴用其长度表示。输出即为是否能用所有的火柴拼成正方形。
示例 1:
输入: [1,1,2,2,2]
输出: true
解释: 能拼成一个边长为2的正方形,每边两根火柴。
示例 2:
输入: [3,3,3,3,4]
输出: false
解释: 不能用所有火柴拼成一个正方形。
注意:
- 给定的火柴长度和在
0
到10^9
之间。 - 火柴数组的长度不超过15。
dfs,注意剪枝条件
class Solution {
public:
map<int,int> mp;
int n;
bool res=false;
long long av;
bool makesquare(vector<int>& nums) {
n=nums.size() ;
long long sum=0;
for(int i=0; i<n; i++) {
sum+=nums[i];
if(mp.count(nums[i])==0)
mp[nums[i]]=1;
else
mp[nums[i]]++;
}
av=sum/4;
if(n==0||sum%4!=0)
return false;
map<int,int>::iterator it1;
it1=mp.begin();
long long isum=it1->first;
mp[it1->first]--;
dfs(1,isum,0);
mp[it1->first]++;
return res;
}
void dfs(int il,long long isum,int sq) {
if(il==n&&sq==3) {
res=true;
return;
}
if(isum==av*(sq+1)) sq++;
else if(isum>av*(sq+1)) return;
if(res) return;
map<int,int>::iterator it1,it2;
for(it1=mp.begin(); it1!=mp.end(); it1++) {
if(mp[it1->first]>0) {
mp[it1->first]--;
dfs(il+1,isum+it1->first,sq);
mp[it1->first]++;
}
}
}
};
class Solution {
public:
bool makesquare(vector<int>& nums) {
if(nums.empty()||nums.size()<4) return false;
int sum = accumulate(nums.begin(),nums.end(),0);
if(sum % 4 != 0) return false;
vector<int> sums(4,0); //长度为4的数组sums来保存每个边的长度和
sort(nums.rbegin(),nums.rend());
return helper(nums,sums,0,sum/4);
}
bool helper(vector<int>& nums,vector<int>& sums,int pos,int target){
if(pos >= nums.size()){
return sums[0] == target && sums[1] == target && sums[2] == target && sums[3] == target;
}
//对于当前这个火柴,尝试拼入上下左右四个边
for(int i=0;i<4;++i){
if(sums[i]+nums[pos] > target) continue;
sums[i] += nums[pos]; //把当前火柴从i个边中拿出来,好尝试下一条边
if(helper(nums,sums,pos+1,target)) return true; //如果这个火柴被成功使用,就开始尝试拼下一根火柴
sums[i] -= nums[pos]; //用当前火柴拼第i个边
}
return false;
}
};
---------------------
作者:Hello_GY
来源:CSDN
原文:https://blog.csdn.net/qq_40803710/article/details/80274628
版权声明:本文为博主原创文章,转载请附上博文链接!