/**
*
*
形如:1/a 的分数称为单位分数。
可以把1分解为若干个互不相同的单位分数之和。
例如:
1 = 1/2 + 1/3 + 1/9 + 1/18
1 = 1/2 + 1/3 + 1/10 + 1/15
1 = 1/3 + 1/5 + 1/7 + 1/9 + 1/11 + 1/15 + 1/35 + 1/45 + 1/231
等等,类似这样的分解无穷无尽。
我们增加一个约束条件:最大的分母必须不超过30
请你求出分解为n项时的所有不同分解法。
数据格式要求:
输入一个整数n,表示要分解为n项(n<12)
输出分解后的单位分数项,中间用一个空格分开。
每种分解法占用一行,行间的顺序按照分母从小到大排序。
例如,
输入:
4
程序应该输出:
1/2 1/3 1/8 1/24
1/2 1/3 1/9 1/18
1/2 1/3 1/10 1/15
1/2 1/4 1/5 1/20
1/2 1/4 1/6 1/12
*
*
形如:1/a 的分数称为单位分数。
可以把1分解为若干个互不相同的单位分数之和。
例如:
1 = 1/2 + 1/3 + 1/9 + 1/18
1 = 1/2 + 1/3 + 1/10 + 1/15
1 = 1/3 + 1/5 + 1/7 + 1/9 + 1/11 + 1/15 + 1/35 + 1/45 + 1/231
等等,类似这样的分解无穷无尽。
我们增加一个约束条件:最大的分母必须不超过30
请你求出分解为n项时的所有不同分解法。
数据格式要求:
输入一个整数n,表示要分解为n项(n<12)
输出分解后的单位分数项,中间用一个空格分开。
每种分解法占用一行,行间的顺序按照分母从小到大排序。
例如,
输入:
4
程序应该输出:
1/2 1/3 1/8 1/24
1/2 1/3 1/9 1/18
1/2 1/3 1/10 1/15
1/2 1/4 1/5 1/20
1/2 1/4 1/6 1/12
*/
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
int n = input.nextInt();
List<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>();
dfs(n, 0, 0.0,res,new ArrayList<Integer>());
//遍历集合输出
for(int i=0;i<res.size();i++){
for(int j=0;j<res.get(i).size();j++){
System.out.print("1/"+res.get(i).get(j)+"\t");
}
System.out.println();
}
}
public static boolean dfs(int n,int cur,double sum,List<ArrayList<Integer>> res,List<Integer> now)
{
//cur:当前项
//如果当前总和已经大于1.0 或者 当前刚好为n项但是其值不等于1.0则返回false(因为可能存在精度的问题,1.0不应该直接写等号,应该用1.0减去一个足够小的数字,比如1e-8)
if(sum > 1.0 || (cur==n) && Math.abs(sum-1.0)>=1e-8){
return false;
}
//如果满足就可以将这组结果存入res并返回true
else if(cur==n && Math.abs(sum-1.0)<1e-8){
res.add(new ArrayList<Integer>(now));
return true;
}
//因为每个数字(分母)是递增的,所以没必要每次都从1 开始。判断如果当前结果为空则从1开始,否则从上次得到的那值+1开始。 遍历每个数字
int i = now.isEmpty()?1:now.get(now.size()-1)+1;
for(;i<30;i++){
//因为保证没有重复的数字,要加一个if(now.indexOf(i) != -1)判断是否存在
if(now.indexOf(i) != -1) continue;
now.add(i);
if(dfs(n,cur+1,sum+1.0/(i*1.0),res,now)){
//假设 2 3 9 18 四个数字是ok的,删除最后一个18
now.remove(now.size()-1);
//既然 2 3 9 18 可以构成1,那么 2 3 9 19 是不可能的,所以返回false
return false;
}
//回溯,移除i,进行下一轮查找
now.remove(now.size()-1);
}
return false;
}