9.带分数
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
解析
核心考点 :典型的全排列+check
枚举1 - 9的全排列,对每个全排列再次枚举"+号"和"/号"的位置,形成了枚举+再枚举的做题逻辑。编写一个通用全排列模板:
public static void main(String[] args) {
int[] arr = {}; //可切换成其他基本数据类型
f(0, arr); //从第1位开始枚举
}
private static void f(int k, int[] arr) {
if(k == arr.length) return; //得到一个全排列-此时arr里存的值就是该全排列
for (int i = k; i < arr.length; i++) {
int tmp = arr[i];
arr[i] = arr[k];
arr[k] = tmp;
f(k+1, arr); //从下一位开始枚举
//恢复状态
tmp = arr[i];
arr[i] = arr[k];
arr[k] = tmp;
}
}
每枚举好一个全排列后,对该全排列进行"+号"和"/号"位置的枚举,以以下为例:
为了计算方便,枚举"+号"和"/号"位置时下标从0开始,那么+号范围 i ∈ [0, 6] ---- /号范围 j ∈ [i+1, 7]。
for (int i = 0; i <= 6; i++) {
for (int j = i+1; j <= 7; j++) {
......
}
+号,/号位置枚举好后,当前全排列就被分割成了三部分:+号前,+号和/号之间、/号后,各部分在数组中的索引范围分别对应[0 , i]、[i+1, j]、[j+1,8].
下一步,定义aToInt方法将索引范围对应的数组段转换成int数据:
private static int aToInt(int i, int j) {
String s = "0";
for (int k = i; k <= j; k++) {
s += arr[k];
}
return Integer.valueOf(s);
}
解题代码:
private static int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9};
private static int N;
private static int ans = 0;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
N = in.nextInt();
in.close();
f(0); //全排列函数
System.out.println(ans);
}
private static void f(int k) {
if(k == arr.length) { //得到一个全排列
check();
}
for (int i = k; i < arr.length; i++) {
int tmp = arr[i];
arr[i] = arr[k];
arr[k] = tmp;
f(k+1);
tmp = arr[i];
arr[i] = arr[k];
arr[k] = tmp;
}
}
private static void check() {
//枚举+号、/号
for (int i = 0; i <= 6; i++) {
for (int j = i+1; j <= 7; j++) {
int first = aToInt(0, i);
int second = aToInt(i+1, j);
int third = aToInt(j+1, arr.length-1);
if( second % third == 0 && first + second / third == N) {
ans++;
}
}
}
}
private static int aToInt(int i, int j) {
String s = "0";
for (int k = i; k <= j; k++) {
s += arr[k];
}
return Integer.valueOf(s);
}