和为T
问题描述
从一个大小为n的整数集中选取一些元素,使得它们的和等于给定的值T。每个元素限选一次,不能一个都不选。
输入格式
第一行一个正整数n,表示整数集内元素的个数。
第二行n个整数,用空格隔开。
第三行一个整数T,表示要达到的和。
第二行n个整数,用空格隔开。
第三行一个整数T,表示要达到的和。
输出格式
输出有若干行,每行输出一组解,即所选取的数字,按照输入中的顺序排列。
若有多组解,优先输出不包含第n个整数的;若都包含或都不包含,优先输出不包含第n-1个整数的,依次类推。
最后一行输出总方案数。
若有多组解,优先输出不包含第n个整数的;若都包含或都不包含,优先输出不包含第n-1个整数的,依次类推。
最后一行输出总方案数。
样例输入
5
-7 -3 -2 5 9
0
-7 -3 -2 5 9
0
样例输出
-3 -2 5
-7 -2 9
2
-7 -2 9
2
数据规模和约定
1<=n<=22
T<=maxlongint
集合中任意元素的和都不超过long的范围
T<=maxlongint
集合中任意元素的和都不超过long的范围
这个答案运行超时只能得90分(没去试把scanner换成buffered,应该是这个问题,否则就是又爆栈了(╯‵□′)╯炸弹!•••*~●)。一开始看题知道是dfs,但是不知道怎么处理,然后看了两个博主的代码。
(1.https://blog.csdn.net/Y734493585/article/details/88387342,2.https://blog.csdn.net/liuchuo/article/details/56676828)
在第一个博客里我终于明白了dfs的过程,这回是彻底清楚了,然后在二里面,老老实实的把代码走了一遍(写了快两张草纸(┗|`O′|┛ 嗷~~))因为我一开始实在是想不明白,我总觉得dfs只能(1)(1,2)
...(1,2,3,4,5)这个样子。在草纸上写了一遍后发现确实通过push和pop把所有得可能都给找出来了。
(
然后是dfs的基本过程。
1,2,3
2,3
3
邻接表从1开始,先找1的下一个子节点2,然后从2开始找,找2的子节点3,然后再3。3没有则这条路结束(1,2,3)
然后再执行(1,3).
然后是(2,3)最后(3)
)
两个博客的差别在于最后判断存储数字可能的栈是否有值时有小的区别,还有博客一没有把访问过的节点给标记了(我想了想好像确实啊,找节点是从上往下的,既然走过了,下次就不会找了。可能是还没理解透彻,过几天再看一次( ̄ ‘i  ̄;))
package lanqiao.improve;
import java.io.IOException;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Scanner;
import java.util.Stack;
public class SumT {
public static int cnt = 0, n = 0;//数量
public static int t = 0;//和
public static int[] nums;//数字
public static Stack<String> out = new Stack<>();//最后输出的栈
public static boolean isVisit[];
public static String toString(Iterator<Integer> it){
StringBuilder sb = new StringBuilder();
while (it.hasNext()){
sb.append(it.next()+" ");
}
return sb.toString();
}
public static void dfs(int pos,int tempt,LinkedList<Integer> select,boolean isNone){
for(int i =pos;i>=0;i--){
if(!isVisit[i]){
isVisit[i] = true;
select.push(nums[i]);
dfs(i-1, tempt+nums[i],select ,false );
select.pop();
isVisit[i] = false;
}
}
if(tempt == t && !isNone){
out.push(toString(select.iterator()));
cnt++;
}
}
public static void main(String[] args) throws IOException {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
isVisit = new boolean[n];
nums = new int[n];
for(int i = 0;i<n;i++){
nums[i] = sc.nextInt();
}
t = sc.nextInt();
sc.close();
dfs(n-1,0, new LinkedList<Integer>(),true);
while (!out.isEmpty()){
System.out.println(out.pop());
}
System.out.println(cnt);
}
}

浙公网安备 33010602011771号