题目描述:
100 可以表示为带分数的形式:100 = 3 + 69258 / 714
还可以表示为:100 = 82 + 3546 / 197
注意特征:带分数中,数字1~9分别出现且只出现一次(不包含0)。
类似这样的带分数,100 有 11 种表示法。
题目要求:
从标准输入读入一个正整数N (N<1000*1000)
程序输出该数字用数码1~9不重复不遗漏地组成带分数表示的全部种数。
注意:不要求输出每个表示,只统计有多少表示法!
例如:
用户输入:
100
程序输出:
11
再例如:
用户输入:
105
程序输出:
6
资源约定:
峰值内存消耗(含虚拟机) < 64M
CPU消耗 < 3000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意:不要使用package语句。不要使用jdk1.6及以上版本的特性。
注意:主类的名字必须是:Main,否则按无效代码处理。
思路: 9个数字的全排列
public class Main{
private static int res = 0;
static int inputNumber = 0;
//全排列可以解决很多问题
//全排列需要将所有的数字存储到数组中
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
inputNumber = sc.nextInt();
int[] arr = {1,2,3,4,5,6,7,8,9};
fullArray(arr,0);
System.out.println(res);
}
//全排列模板:给一个数组,一个变量,给边界,对每一种可能,往下走一走(在循环中进行递归)
//确认某一个排列的第i位
private static void fullArray(int[] arr,int i) {
//全部确认
if (i == 9){
check(arr);
return;
}
//选定第i位
for (int j = i; j < arr.length; j++) {
//将第j位和第i为交换
int temp = arr[j];
arr[j] = arr[i];
arr[i] = temp;
//移交给下一层确认第i + 1位
fullArray(arr,i + 1);
//回溯
temp = arr[j];
arr[j] = arr[i];
arr[i] = temp;
}
}
//穷举+ / 出现的位置
private static void check(int[] arr) {
//+ 前的字符数最多为7
for (int i = 1; i < 8; i++) {
//如果 + 前面的数大于了inputNumber,退出
int beforeAdd = toInt(arr, 0, i); //加号前面的数
if(beforeAdd >= inputNumber){
continue;
}
for (int j = 1; j < 9 - i; j++) {
int beforeDivision = toInt(arr,i,j);
int afterDivision = toInt(arr,i + j, 9 - i - j);
if(beforeDivision % afterDivision == 0 && beforeAdd + beforeDivision / afterDivision == inputNumber){
res++;
}
}
}
}
private static int toInt(int[] arr, int pos, int length) {
int t = 1;
int res = 0;
for (int i = pos + length - 1; i >= pos; i--) {
res += arr[i] * t;
t *= 10;
}
return res;
}
}