题目大意:
给你n个棍子,要求将所有的棍子都用上,拼成一个正方形。
解析:
回溯+剪枝,用一个pos来记录搜索到的位置,当下次搜索时,从上一次结束的位置开始搜索。
给你n个棍子,要求将所有的棍子都用上,拼成一个正方形。
解析:
回溯+剪枝,用一个pos来记录搜索到的位置,当下次搜索时,从上一次结束的位置开始搜索。
总结:这题写剪枝的时候把dfs(i+1,sum+s[i],cnt)写成了dfs(pos+1,sum+s[i],cnt),结果一直超时,浪费了好多时间来找错误,下次要吸取教训。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 30;
int s[N];
int vis[N];
int n;
int tar;
bool flag;
void dfs(int pos,int sum,int cnt) {
if(cnt == 3) {
flag = true;
return ;
}
if(sum == tar) {
dfs(0,0,cnt+1);
}
if(flag) {
return;
}
for(int i = pos; i < n; i++) {
if(!vis[i]) {
if(sum + s[i] <= tar) {
vis[i] = true;
dfs(i+1,sum+s[i],cnt);
vis[i] = false;
int j;
for(j = i+1; j < n; j++) {
if(s[j] != s[i]) {
break;
}
}
i = j-1;
if(flag) {
return ;
}
}
}
}
}
bool cmp(int a,int b) {
return b < a;
}
int main() {
int t;
scanf("%d",&t);
while(t--) {
int sum = 0;
scanf("%d",&n);
for(int i = 0; i < n; i++) {
scanf("%d",&s[i]);
sum += s[i];
}
if(sum % 4 != 0) {
printf("no\n");
continue;
}
tar = sum / 4;
sort(s,s+n,cmp);
if(s[0] > tar) {
printf("no\n");
continue;
}
memset(vis,0,sizeof(vis));
flag = false;
dfs(0,0,0);
if(flag) {
printf("yes\n");
}else {
printf("no\n");
}
}
return 0;
}