题目大意:给出一列数据,不多于30个。如果其中的两个或多个数之和等于这组数据中的另一个数,如{1,2,3}这个数组中存在等式1+2=3,输出这个等式。找出满足条件的所有等式。如果,找不到符合条件的,输出“Can’t find any equations.”。
解法:把这个数组的所有数字排序。首先,从小到大开始累加数字,直到和超过数组的最大值,这样我们可以知道,等式左边最多可以有几个数字。然后,从两个加数开始,用深度优先的方法,从左往右搜索,寻找是否存在满足条件的等式。依次递增搜索的深度。
参考代码:
//参考了这篇日志http://blog.csdn.net/scnu_jiechao/article/details/8134952 #include<iostream> #include<algorithm> using namespace std; int M[32],C[32],n,visited[32],flag; //cur 表示当前使用数字的个数,dest表示这一轮需要的加数个数,temp表示当前和,last表示前一个加数的下标 void dfs(int cur,int dest, int temp, int last); //检查能否在数组中找到对应的求和数 int exist(int last, int n, int tsum); int main(){ int cases,i,j,m,deep; cin>>cases; while(cases--){ cin>>n; for(i=0;i<n;i++) cin>>M[i]; sort(M,M+n); //输入数字不一定按照顺序,要先排序 int sum=0; i=0; while(sum<=M[n-1]) sum+=M[i++]; deep=i-1; flag=0; for(i=2;i<=deep;i++){ dfs(0,i,0,0); } if(!flag) cout<<"Can't find any equations."<<endl; cout<<endl; } return 0; } void dfs(int cur,int dest, int tsum, int last){ if(cur==dest){ //等号左边数的个数等于本轮搜索的加数个数 if(exist(last,n,tsum)){ //能否找到一个数等于当前和,找到就输出,找不到就放弃; for(int i=0;i<dest-1;i++) cout<<C[i]<<"+"; //C数组暂时保存前面的加数 cout<<C[dest-1]<<"="<<tsum<<endl; flag=1; } } else{ for(int i=last;i<n;i++){ //如果加数数目不够,在余下的数里寻找 if(tsum+M[i]<=M[n-1]&&C[cur-1]!=M[i]){ C[cur]=M[i]; //当前数字入栈 dfs(cur+1,dest,tsum+M[i],i); } } } } int exist(int x, int y, int v){ int m; while(x < y) { m = x + (y-x)/2; //用二分法来找等式右边的数字 if(M[m] == v) return 1; else if(M[m] > v) y = m; else x = m + 1; } return 0; }