poj 2362スクウェア(簡単な深さ検索+剪定)
1927 ワード
テーマリンク:http://poj.org/problem?id=2362
タイトルの大意:
tグループの入力データがあります.各グループのデータは1行です.1行目は木の棒の本数(4<=n==20)で、木の棒の長さ(1<=stick<=10000)
正方形にするかどうかを判断します.
解析:
剪定の深さ:
剪定:1、木の棒の数は4より小さい.
2、総棒の長さ/4=正方形の辺の長さは整数ではない.
3、最大の棒の長さは正方形の長さより大きいです.
4、1、2、3を除いて、3つの辺を探せばいいです.
コード:
タイトルの大意:
tグループの入力データがあります.各グループのデータは1行です.1行目は木の棒の本数(4<=n==20)で、木の棒の長さ(1<=stick<=10000)
正方形にするかどうかを判断します.
解析:
剪定の深さ:
剪定:1、木の棒の数は4より小さい.
2、総棒の長さ/4=正方形の辺の長さは整数ではない.
3、最大の棒の長さは正方形の長さより大きいです.
4、1、2、3を除いて、3つの辺を探せばいいです.
コード:
#include <iostream>
#include <algorithm>
using namespace std;
int n ;//
int side; //
int cmp(int a, int b) {
return a > b;
}
//stick ,vis , num , len
//s stick ,
bool dfs(int *stick, bool *vis, int num, int len, int s) {
if(num == 3) // ,
return true;
for(int i=s; i<n; i++) {
// ,
if(vis[i])
continue;
vis[i] = true;
// side, num ,len = len+stick[i],
if(len+stick[i] < side) {
// , ,dfs() True
if(dfs(stick, vis, num, len+stick[i], i))
return true;
}
// side, num+1, len=0,s=0,
else if(len+stick[i] == side) {
// , ,dfs() True
if(dfs(stick, vis, num+1, 0, 0))
return true;
}
vis[i] = false;
}
return false;
}
int main(void) {
int time;
//freopen("2.in", "r", stdin);
//freopen("2.out", "w", stdout);
cin >> time;
while(time--) {
int sum = 0;
cin >> n;
int stick[21];
bool vis[21];
int maxside = 0;
for(int i=0; i<n; i++) {
cin >> stick[i];
vis[i] = false;
if(maxside < stick[i])
maxside = stick[i];
sum += stick[i];
}
// 1、 4 , ,
if(n<4 || sum%4 || maxside>sum/4) {
cout << "no" << endl;
continue;
}
sort(stick, stick+n, cmp);
side = sum / 4;
if(dfs(stick, vis, 0, 0, 0))
cout << "yes" << endl;
else
cout << "no" << endl;
}
return 0;
}