第五届蓝桥杯第6题【单位分数】

形如: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

再例如,
输入:
5
程序应该输出:
1/2 1/3 1/12 1/21 1/28
1/2 1/4 1/6 1/21 1/28
1/2 1/4 1/7 1/14 1/28
1/2 1/4 1/8 1/12 1/24
1/2 1/4 1/9 1/12 1/18
1/2 1/4 1/10 1/12 1/15
1/2 1/5 1/6 1/12 1/20
1/3 1/4 1/5 1/6 1/20

资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 2000ms

请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意:不要使用package语句。不要使用jdk1.7及以上版本的特性。
注意:主类的名字必须是:Main,否则按无效代码处理`

import java.util.Scanner;
 
 
public class 单位分数 {
    /**
     * 
     * @param num
     *            Max项数
     * @param a
     *            存放分母的数组
     * @param k
     *            从0到num
     */
    public static void getResult(int num, int a[], int k) {
        if (num == k) {// 数组a赋值结束,判断是否符合条件
            judge(a);
            return; // 跳出此次函数到上一个f函数,重新对a进行赋值
        }
        for (int i = 2; i < 30; i++) {// 分母最大为30
            a[k] = i;
            getResult(num, a, k + 1);
        }
    }

        //判断是否满足题目的条件
    public static void judge(int a[]) {
        int rightSum = 1;
        int smallSum = 1;
        int leftSum = 0;
        // 筛选等于,后面大于前面的数---要求按分母从小到大
        for (int k = 0; k < a.length; k++) {
            for (int l = k + 1; l < a.length; l++) {
                if (a[k] >= a[l]) {
                    return;
                }
            }
        }
        // 判断分母数组是否符合要求
        // 1/a+1/b+1/c==1
        // a*c+b*c+a*b==a*b*c
        for (int i = 0; i < a.length; i++) {
            rightSum = rightSum * a[i];
            for (int j = 0; j < a.length; j++) {
                if (i == j) {
                    continue;
                }
                smallSum = smallSum * a[j];
            }
            leftSum = leftSum + smallSum;
            smallSum = 1; // smallSum需要清1
        }
        // 说明满足找到满足条件的分解方法,输出
        if (rightSum == leftSum) {
            print(a);
        } else {
            return;
        }
    }

    // 打印
    public static void print(int a[]) {
        System.out.println();
        for (int i = 0; i < a.length; i++) {
            if (i == a.length - 1) {
                System.out.print("1/" + a[i] + " ");
            } else {
                System.out.print("1/" + a[i] + "+");
            }
        }

    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int num = sc.nextInt();
        int a[] = new int[num];
        int k = 0;
        getResult(num, a, k);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值