版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Kwong_young/article/details/79703485
题目
问题描述
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的全排列找出来
然后用找出来的数去试探哪种符合题目要求
对于n=a+b/c
首先a要小于n,b必须是c的整数倍。所以就有了剪枝。
因为b大于c,所以一共9位数减去a的位数,b最少要占一半,最多可以占9-a再减1(减的1是c)。
代码
import java.util.Scanner;
public class Main {
static boolean vis[] = new boolean[10];
static int maze[] = new int[10];
static int count;
static int n;
public static void main(String[] args) {
Scanner scan=new Scanner(System.in);
for(int i=0;i<10;i++) {
vis[i] = false;
maze[i] = -1;
}
n=scan.nextInt();
count = 0;
dfs(0);
System.out.println(count);
}
public static void dfs(int step) { //深搜
if(step==9) {
find();
return ;
}
for(int i=0;i<9;i++) { //求全排列
if(!vis[i]) {
vis[i]= true;
maze[step]=i+1;
dfs(step+1);
vis[i] = false;
}
}
}
public static void find() { //查找有没有合适的组合。
int len = Integer.toString(n).length();
for(int i=0;i<len;i++) { //a的长度可以为1到len
int a=0,b=0,c=0;
a=sum(0,i+1); //因为下面的sum求和函数中end是取不到的,所以末尾是i+1
if(a>n) return; //剪枝
for(int j=(9-i)/2;j<8-i;j++) { //试探b的长度可以为多少
b=sum(i+1,j+i+1);
c=sum(j+i+1,9);
if(b>c&&n==a+b/c&&b%c==0) { //查找满足要求的组合数
count++;
//System.out.println(a+" "+b+" "+c);
}
}
}
}
public static int sum(int begin,int end) {
int a=0;
for(int i=begin;i<end;i++) {
a=a*10+maze[i];
}
return a;
}
}