先分层,然后进行深度优先遍历。
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 30 + 10; //每组数据最多有30个数
int n, ok, C[maxn], a[maxn]; //n为每组数据的个数,ok标记是否有等式存在,C用来存路径,a为输入的数组
bool search(int *a, int x, int y, int v) //二分搜索,返回搜索成功与否
{
int m;
while(x < y)
{
m = x + (y-x)/2;
if(a[m] == v) return 1;
else if(a[m] > v) y = m;
else x = m + 1;
}
return 0;
}
void dfs(int cur, int des, int cur_sum, int last) //深度优先遍历,cur为目前层数,des为目标层数,cur_sum为目前数的和,
{
int i;
if(cur == des) //当目前层数==目标层数的时候
{
if(search(a, last, n, cur_sum)) //寻找数组中有没有这个和数存在(为节省时间,从last开始白手搜索)
{
for(i = 0; i < cur-1; i++) //输出
cout<<C[i]<<"+";
cout<<C[cur-1]<<"="<<cur_sum<<endl;
ok = 1; //修改全局变量ok,说明有等式存在
}
}
else for(i = last; i < n; i++) //当目前层数!=目标层数的时候
{
if(cur_sum + a[i] <= a[n-1] && C[cur-1] != a[i]) //第二个比较没有的话数字就可以重复出现了
{
C[cur] = a[i]; //记录路径
dfs(cur+1, des, cur_sum + a[i], i); //递归调用
}
}
}
int main()
{
int N, i;
cin>>N; //N组测试数据
while(N--)
{
cin>>n;
for(i = 0; i < n; i++)
cin>>a[i];
sort(a, a+n); //输完数据后先排序
int sum = 0;
for(i = 0; i < n; i++) //找最多可以几个数相加,即最大层数
{
sum += a[i];
if(sum >= a[n-1])
break;
}
int len = i+1; //最大层数
ok = 0; //注意这里标记为0
for(i = 2; i <= len; i++) //对每层进行搜索
dfs(0, i, 0, 0);
if(!ok)
cout<<"Can't find any equations."<<endl;
cout<<endl; //小心,这里的最后一组也要加空行
}
return 0;
}