问题描述:
100 可以表示为带分数的形式:100 = 3 + 69258 / 714。
还可以表示为:100 = 82 + 3546 / 197。
注意特征:带分数中,数字1~9分别出现且只出现一次(不包含0)。
类似这样的带分数,100 有 11 种表示法。
输入格式:
从标准输入读入一个正整数N (N<1000*1000)
输出格式:
程序输出该数字用数码1~9不重复不遗漏地组成带分数表示的全部种数。
注意:不要求输出每个表示,只统计有多少表示法!
题目分析:
利用递归回溯求出1~9的全排列,再在这9个数中 分为三段
一段是加法前面的数,一段是被除数,一段是除数
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
/**
*
* count作为最后的结果
* number是输入
* used[] 存9个数,代表1-9是否有被使用
* nums存的是当前选择的数字
*/
public class Main{
static int count;
static int number;
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
number = s.nextInt();
boolean used[] = new boolean[9];
int[] nums = new int[9];
dfs(used, nums, 1);
System.out.println(count);
}
public static void dfs(boolean[] used, int[] nums, int index)// 求全排列
{
if (index > 9)// 当超过9个数
{
if (daifenshu(nums))// 判断是否是带分数
{
count++;
}
return;
}
for (int i = 1; i <= 9; i++) {
if (!used[i - 1]) {
used[i - 1] = true;
nums[index - 1] = i;
index++;
dfs(used, nums, index);
//回溯
used[i - 1] = false;
index--;
nums[index - 1] = 0;
}
}
}
public static boolean daifenshu(int nums[]) {
for (int i = 0; i < 7; i++) { //加号的位置
int jia_num = 0;
for (int j = 0; j <= i; j++) {
jia_num = jia_num * 10 + nums[j];
}
if (jia_num > number) {
return false; // 如果+前面的数比输入的大了,直接返回false
}
for (int j = i + 1; j < 8; j++) {//除号的位置
int beichu_num = 0;
int chu_num = 0;
for (int j2 = i + 1; j2 <= j; j2++) {
beichu_num = beichu_num * 10 + nums[j2];
}
for (int j2 = j + 1; j2 < 9; j2++) {
chu_num = chu_num * 10 + nums[j2];
}
if (beichu_num % chu_num == 0 && beichu_num / chu_num + jia_num == number) {
// System.out.println("前面:"+jia_num+" 被除数:"+beichu_num+" 除数:"+chu_num);
return true;
}
}
}
return true;
}
}