HDU 1518 Square(回溯)

题目大意:
给你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;
}


你可能感兴趣的:(HDU,Square,1518)