00 可以表示为带分数的形式: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,否则按无效代码处理。
分析:先求出数字1-9的全排列再去判断是够满足题意即可
关键是如何对一个排列判断,由题目式子可以看到,每个数是有一定的限制的
首先,第一个数肯定位数小于数字n,其次,后面两个数的话,第二个数的长度肯定大于等于第三个,也就是值的大小关系。
那么第二个数的长度肯定大于等于(总的长度减去第一个数的长度的剩下的长度的一半)
比如:1234567989这个序列,假设第一个数为1,那么第一个数长度肯定至少大于(9-1)/2;
为什么我们要强调长度呢,因为我的思路是转化为字符串处理的,截取函数当然要用到长度了,
看代码吧
import java.util.*;
public class Main {
static Scanner in = new Scanner(System.in);
static int cnt;
static boolean[] vis = new boolean[10];
static int[] a = new int[10];
//检查这个排列是否满足要求
static void isOk(int n){
int len = String.valueOf(n).length();
String s = "";
for(int i =0;i < 9;i++)
s += a[i];
//System.out.println(s);
int k = 0,j = 0,num1,num2,num3;
//假设 num1 + num2/num3 = n;
for(k = 1;k <= len;k++){//枚举第一个数num1,长度肯定不会超过n的长度
num1 = Integer.valueOf(s.substring(0, k));
if(num1<n){
for(j = k + (9-k)/2;j < 9;j++){//枚举第二个和第三个数,第二个数的长度肯定大于等于第三个
num2 = Integer.valueOf(s.substring(k,j));
num3 = Integer.valueOf(s.substring(j,9));
if(num2>num3&&num2%num3==0){//满足条件
if(num1+num2/num3==n)
cnt++;
}
}
}
}
}
//数字1-9的全排列
static void dfs(int sp,int n){
if(sp >= 9){
isOk(n);
return;
}
for(int i = 1;i <= 9;i++){
if(!vis[i]){
vis[i] = true;
a[sp] = i;
dfs(sp+1,n);
vis[i] = false;
}
}
}
public static void main(String[] args) {
int n = in.nextInt();
Arrays.fill(vis, false);
long s = System.currentTimeMillis();
cnt = 0;
dfs(0,n);
long e = System.currentTimeMillis();
System.out.println(e-s);//计算程序运行时间
System.out.println(cnt);
}
}
补:上面那种思路太繁琐了,这里补上更加简洁版本的代码
思路: 由于题目是个等式,我们可以采取知二求三的方法来降低复杂度,只需要枚举整数部分和分母部分即可,然后判断数字1-9是否都曾出现过,这样简单很多,看代码:
import java.util.*;
public class Main {
static Scanner in = new Scanner(System.in);
static int n,sum;
static char[] num = {'1','2','3','4','5','6','7','8','9'};
public static void main(String[] args) {
n = in.nextInt();
int i,j,t;
String s = "";
boolean f = false;
for(i = 1;i < n;i++) {//整数部分
for(j = 2;j < 10000;j++) {//分母部分
t = (n - i) * j;//分子
s = "" + i + j + t;
if(s.length()!=9)
continue;
f = false;
for(int k = 0;k < num.length;k++) {
int index = s.indexOf(num[k]);
if(index==-1) {//1到9之一没有出现,不符合条件
f = false;
break;
}
f = true;
}
if(f)
sum++;
}
}
System.out.println(sum);
}
}