Java实现 历届试题 带分数

问题描述

100 可以表示为带分数的形式:100 = 3 + 69258 / 714。

还可以表示为:100 = 82 + 3546 / 197。

注意特征:带分数中,数字1~9分别出现且只出现一次(不包含0)。

类似这样的带分数,100 有 11 种表示法。

输入格式

从标准输入读入一个正整数N (N<1000*1000)
输出格式

程序输出该数字用数码1~9不重复不遗漏地组成带分数表示的全部种数。

注意:不要求输出每个表示,只统计有多少表示法!
样例输入1
100
样例输出1
11

样例输入2
105
样例输出2
6

思路: 对于这道题,可以分成两部分来做,第一部分是把数字1-9的排法全排列一遍,如:[1,2,3,4,5,6,7,8,9],[2,1,3,4,5,6,7,8,9],[9,8,7,6,5,4,3,2,1]…注意排列方法,不能把排列排重
第二部分,我们就可以把排列好的数字 按照题目要求的带分数的型式 找出可以表示这个整数的表示法,统计数量。

代码示例:

import java.util.Scanner;

public class 带分数 {

	static int n;
	static int count = 0;

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		// 输入一个正整数
		n = sc.nextInt();
		sc.close();

		// 将数字1-9存入数组中
		int[] array = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
		// 将数字1-9进行全排列
		arrange(array, 0, array.length - 1);

		// 得到带分数结果
		System.out.println(count);
	}
	// 全排列
	static void arrange(int[] array, int start, int end) {
		if (start == end) {
			// for (int i : array)
			// {System.out.print(i);str.append(i);}System.out.println();
			// count++;
			
			//将数字顺序排列好后,用带分数的形式计算结果
			result(array);
			return;
		}
		// 排列置换
		for (int i = start; i <= end; i++) {
			swap(array, i, start);
			arrange(array, start + 1, end);
			swap(array, i, start);
		}
	}

	// 用于全排列是做数值交换
	static void swap(int[] array, int i, int j) {
		int temp = array[i];
		array[i] = array[j];
		array[j] = temp;
	}

	static void result(int[] array) {
		// 输入的正整数的数字位数
		int lenN = String.valueOf(n).length();
		// 相加的数
		int add = 0;
		for (int i = 0; i < lenN; i++) {
			add = add * 10 + array[i];
			if (add > n)
				return;
			
			//分数分子,需要是浮点型,保留小数
			double divisor = 0;
			for (int j = i + 1; j < array.length - 1; j++) {
				divisor = divisor * 10 + array[j];
				
				// 分数分母
				double dividend = 0;
				for (int k = j + 1; k < array.length; k++) {
					dividend = dividend * 10 + array[k];
				}
				// 作比较
				if (n == add + (divisor / dividend)) {
					// System.out.println(add + "+" + divisor + "/" + dividend +
					// "=" + (add + (divisor / dividend)));
					count++;
				}
			}
		}
	}
}

在这里插入图片描述

第二种解法:改了一下递归全排列的方式,想让递归看起来更简单一点,没想,空间复杂度又增加了一点

import java.util.Scanner;

public class 带分数02 {
	static int n;

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		n = sc.nextInt();
		arrange(1);
		System.out.println(count);

	}

	static int count = 0;
	static int[] array = new int[10];
	static int[] temp = new int[10];
	static void arrange(int start) {
		if (start == 10) {
			result();
			return;
		}

		for (int i = 1; i <= 9; i++) {
			if (temp[i] == 0) {
				temp[i] = 1;
				array[i] = start;
				arrange(start + 1);
				temp[i] = 0;
			}
		}

	}

	static void result() {
		int a = 0;
		for (int i = 1; i <= String.valueOf(n).length(); i++) {
			a = a * 10 + array[i];
			if (a > n)
				return;
			double b = 0;
			for (int j = i + 1; j < array.length - 1; j++) {
				b = b * 10 + array[j];
				double c = 0;
				for (int k = j + 1; k < array.length; k++) {
					c = c * 10 + array[k];
				}
				if (n == a + (b / c)) {
					count++;
				}
			}
		}
	}
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值